@neo4j-ndl/react-graph 2.1.5 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/lib/cjs/_generated/style-rules/index.js +7 -1
  2. package/lib/cjs/_generated/style-rules/index.js.map +1 -1
  3. package/lib/cjs/_generated/style-rules/literal-schemas.js +32 -1
  4. package/lib/cjs/_generated/style-rules/literal-schemas.js.map +1 -1
  5. package/lib/cjs/_generated/style-rules/range-utils.js +46 -0
  6. package/lib/cjs/_generated/style-rules/range-utils.js.map +1 -0
  7. package/lib/cjs/index.js +2 -1
  8. package/lib/cjs/index.js.map +1 -1
  9. package/lib/cjs/styling/compile-graph-styles.js +56 -16
  10. package/lib/cjs/styling/compile-graph-styles.js.map +1 -1
  11. package/lib/cjs/styling/style-types.js +19 -19
  12. package/lib/cjs/styling/style-types.js.map +1 -1
  13. package/lib/esm/_generated/style-rules/index.js +2 -1
  14. package/lib/esm/_generated/style-rules/index.js.map +1 -1
  15. package/lib/esm/_generated/style-rules/literal-schemas.js +28 -0
  16. package/lib/esm/_generated/style-rules/literal-schemas.js.map +1 -1
  17. package/lib/esm/_generated/style-rules/range-utils.js +43 -0
  18. package/lib/esm/_generated/style-rules/range-utils.js.map +1 -0
  19. package/lib/esm/index.js +1 -1
  20. package/lib/esm/index.js.map +1 -1
  21. package/lib/esm/styling/compile-graph-styles.js +56 -17
  22. package/lib/esm/styling/compile-graph-styles.js.map +1 -1
  23. package/lib/esm/styling/style-types.js +19 -19
  24. package/lib/esm/styling/style-types.js.map +1 -1
  25. package/lib/types/_generated/style-rules/index.d.ts +3 -2
  26. package/lib/types/_generated/style-rules/index.d.ts.map +1 -1
  27. package/lib/types/_generated/style-rules/literal-schemas.d.ts +20 -0
  28. package/lib/types/_generated/style-rules/literal-schemas.d.ts.map +1 -1
  29. package/lib/types/_generated/style-rules/range-utils.d.ts +26 -0
  30. package/lib/types/_generated/style-rules/range-utils.d.ts.map +1 -0
  31. package/lib/types/index.d.ts +2 -2
  32. package/lib/types/index.d.ts.map +1 -1
  33. package/lib/types/styling/compile-graph-styles.d.ts +12 -0
  34. package/lib/types/styling/compile-graph-styles.d.ts.map +1 -1
  35. package/lib/types/styling/style-types.d.ts +168 -33
  36. package/lib/types/styling/style-types.d.ts.map +1 -1
  37. package/package.json +3 -3
@@ -5,7 +5,7 @@
5
5
  * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.resolveNumericLiteral = exports.numericValuesEqual = exports.isBigintLiteral = exports.getNumericWeight = exports.compareNumericValues = exports.clampNumericValue = exports.TimeLiteralSchema = exports.NumericLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.BigintLiteralSchema = exports.parseTimeString = exports.parseLocalDateString = exports.parseDateString = exports.lerpColor = exports.getWeight = void 0;
8
+ exports.resolveRangeLiteral = exports.resolveNumericLiteral = exports.numericValuesEqual = exports.isBigintLiteral = exports.getNumericWeight = exports.compareNumericValues = exports.clampNumericValue = exports.TimeLiteralSchema = exports.RangeLiteralSchema = exports.NumericLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.isTimeLiteral = exports.isLocalDatetimeLiteral = exports.isDatetimeLiteral = exports.DatetimeLiteralSchema = exports.BigintLiteralSchema = exports.parseTimeString = exports.parseLocalDateString = exports.parseDateString = exports.lerpColor = exports.getWeight = void 0;
9
9
  /**
10
10
  *
11
11
  * Copyright (c) "Neo4j"
@@ -36,8 +36,12 @@ Object.defineProperty(exports, "parseTimeString", { enumerable: true, get: funct
36
36
  var literal_schemas_1 = require("./literal-schemas");
37
37
  Object.defineProperty(exports, "BigintLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.BigintLiteralSchema; } });
38
38
  Object.defineProperty(exports, "DatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.DatetimeLiteralSchema; } });
39
+ Object.defineProperty(exports, "isDatetimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isDatetimeLiteral; } });
40
+ Object.defineProperty(exports, "isLocalDatetimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isLocalDatetimeLiteral; } });
41
+ Object.defineProperty(exports, "isTimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isTimeLiteral; } });
39
42
  Object.defineProperty(exports, "LocalDatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.LocalDatetimeLiteralSchema; } });
40
43
  Object.defineProperty(exports, "NumericLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.NumericLiteralSchema; } });
44
+ Object.defineProperty(exports, "RangeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.RangeLiteralSchema; } });
41
45
  Object.defineProperty(exports, "TimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.TimeLiteralSchema; } });
42
46
  var numeric_utils_1 = require("./numeric-utils");
43
47
  Object.defineProperty(exports, "clampNumericValue", { enumerable: true, get: function () { return numeric_utils_1.clampNumericValue; } });
@@ -46,4 +50,6 @@ Object.defineProperty(exports, "getNumericWeight", { enumerable: true, get: func
46
50
  Object.defineProperty(exports, "isBigintLiteral", { enumerable: true, get: function () { return numeric_utils_1.isBigintLiteral; } });
47
51
  Object.defineProperty(exports, "numericValuesEqual", { enumerable: true, get: function () { return numeric_utils_1.numericValuesEqual; } });
48
52
  Object.defineProperty(exports, "resolveNumericLiteral", { enumerable: true, get: function () { return numeric_utils_1.resolveNumericLiteral; } });
53
+ var range_utils_1 = require("./range-utils");
54
+ Object.defineProperty(exports, "resolveRangeLiteral", { enumerable: true, get: function () { return range_utils_1.resolveRangeLiteral; } });
49
55
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CAAqD;AAA5C,wGAAA,SAAS,OAAA;AAAE,wGAAA,SAAS,OAAA;AAC7B,2CAIsB;AAHpB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,6GAAA,eAAe,OAAA;AAEjB,qDAM2B;AALzB,sHAAA,mBAAmB,OAAA;AACnB,wHAAA,qBAAqB,OAAA;AACrB,6HAAA,0BAA0B,OAAA;AAC1B,uHAAA,oBAAoB,OAAA;AACpB,oHAAA,iBAAiB,OAAA;AASnB,iDAOyB;AANvB,kHAAA,iBAAiB,OAAA;AACjB,qHAAA,oBAAoB,OAAA;AACpB,iHAAA,gBAAgB,OAAA;AAChB,gHAAA,eAAe,OAAA;AACf,mHAAA,kBAAkB,OAAA;AAClB,sHAAA,qBAAqB,OAAA","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nexport { getWeight, lerpColor } from './color-utils';\nexport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nexport {\n BigintLiteralSchema,\n DatetimeLiteralSchema,\n LocalDatetimeLiteralSchema,\n NumericLiteralSchema,\n TimeLiteralSchema,\n} from './literal-schemas';\nexport type {\n BigintLiteral,\n DatetimeLiteral,\n LocalDatetimeLiteral,\n NumericLiteral,\n TimeLiteral,\n} from './literal-schemas';\nexport {\n clampNumericValue,\n compareNumericValues,\n getNumericWeight,\n isBigintLiteral,\n numericValuesEqual,\n resolveNumericLiteral,\n} from './numeric-utils';\nexport type { NumericValue } from './numeric-utils';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CAAqD;AAA5C,wGAAA,SAAS,OAAA;AAAE,wGAAA,SAAS,OAAA;AAC7B,2CAIsB;AAHpB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,6GAAA,eAAe,OAAA;AAEjB,qDAU2B;AATzB,sHAAA,mBAAmB,OAAA;AACnB,wHAAA,qBAAqB,OAAA;AACrB,oHAAA,iBAAiB,OAAA;AACjB,yHAAA,sBAAsB,OAAA;AACtB,gHAAA,aAAa,OAAA;AACb,6HAAA,0BAA0B,OAAA;AAC1B,uHAAA,oBAAoB,OAAA;AACpB,qHAAA,kBAAkB,OAAA;AAClB,oHAAA,iBAAiB,OAAA;AAUnB,iDAOyB;AANvB,kHAAA,iBAAiB,OAAA;AACjB,qHAAA,oBAAoB,OAAA;AACpB,iHAAA,gBAAgB,OAAA;AAChB,gHAAA,eAAe,OAAA;AACf,mHAAA,kBAAkB,OAAA;AAClB,sHAAA,qBAAqB,OAAA;AAGvB,6CAAoD;AAA3C,kHAAA,mBAAmB,OAAA","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nexport { getWeight, lerpColor } from './color-utils';\nexport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nexport {\n BigintLiteralSchema,\n DatetimeLiteralSchema,\n isDatetimeLiteral,\n isLocalDatetimeLiteral,\n isTimeLiteral,\n LocalDatetimeLiteralSchema,\n NumericLiteralSchema,\n RangeLiteralSchema,\n TimeLiteralSchema,\n} from './literal-schemas';\nexport type {\n BigintLiteral,\n DatetimeLiteral,\n LocalDatetimeLiteral,\n NumericLiteral,\n RangeLiteral,\n TimeLiteral,\n} from './literal-schemas';\nexport {\n clampNumericValue,\n compareNumericValues,\n getNumericWeight,\n isBigintLiteral,\n numericValuesEqual,\n resolveNumericLiteral,\n} from './numeric-utils';\nexport type { NumericValue } from './numeric-utils';\nexport { resolveRangeLiteral } from './range-utils';\n"]}
@@ -5,7 +5,10 @@
5
5
  * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.NumericLiteralSchema = exports.BigintLiteralSchema = void 0;
8
+ exports.RangeLiteralSchema = exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.NumericLiteralSchema = exports.BigintLiteralSchema = void 0;
9
+ exports.isDatetimeLiteral = isDatetimeLiteral;
10
+ exports.isLocalDatetimeLiteral = isLocalDatetimeLiteral;
11
+ exports.isTimeLiteral = isTimeLiteral;
9
12
  /**
10
13
  *
11
14
  * Copyright (c) "Neo4j"
@@ -94,4 +97,32 @@ exports.TimeLiteralSchema = zod_1.z.object({
94
97
  message: 'time must be a valid ISO 8601 time string (e.g. "14:30:00" or "14:30:00+02:00")',
95
98
  }),
96
99
  });
100
+ function isObjectWithStringKey(value, key) {
101
+ return (typeof value === 'object' &&
102
+ value !== null &&
103
+ key in value &&
104
+ typeof value[key] === 'string');
105
+ }
106
+ /** Returns whether a value is a `{ datetime: string }` wrapper. Does not validate the string. */
107
+ function isDatetimeLiteral(value) {
108
+ return isObjectWithStringKey(value, 'datetime');
109
+ }
110
+ /** Returns whether a value is a `{ localdatetime: string }` wrapper. Does not validate the string. */
111
+ function isLocalDatetimeLiteral(value) {
112
+ return isObjectWithStringKey(value, 'localdatetime');
113
+ }
114
+ /** Returns whether a value is a `{ time: string }` wrapper. Does not validate the string. */
115
+ function isTimeLiteral(value) {
116
+ return isObjectWithStringKey(value, 'time');
117
+ }
118
+ /**
119
+ * A continuous, orderable literal that can be used as a range boundary.
120
+ * Temporal literals resolve to numbers before range interpolation.
121
+ */
122
+ exports.RangeLiteralSchema = zod_1.z.union([
123
+ exports.NumericLiteralSchema,
124
+ exports.DatetimeLiteralSchema,
125
+ exports.LocalDatetimeLiteralSchema,
126
+ exports.TimeLiteralSchema,
127
+ ]);
97
128
  //# sourceMappingURL=literal-schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6BAAwB;AAExB,6CAIsB;AAEtB;;;GAGG;AACU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE;QACrC,OAAO,EAAE,gDAAgD;KAC1D,CAAC;CACH,CAAC,CAAC;AAGH,4EAA4E;AAC/D,QAAA,oBAAoB,GAAG,OAAC,CAAC,KAAK,CAAC;IAC1C,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,2BAAmB;CACpB,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC9D,OAAO,EACL,sEAAsE;KACzE,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iCAAoB,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QACxE,OAAO,EACL,kGAAkG;KACrG,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,EACL,iFAAiF;KACpF,CAAC;CACH,CAAC,CAAC","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { z } from 'zod';\n\nimport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\n\n/**\n * A JSON-safe bigint literal. Native bigint values cannot be serialized as\n * JSON, so persisted style rules can use a signed decimal string instead.\n */\nexport const BigintLiteralSchema = z.object({\n bigint: z.string().regex(/^[+-]?\\d+$/, {\n message: 'bigint must be a signed decimal integer string',\n }),\n});\nexport type BigintLiteral = z.infer<typeof BigintLiteralSchema>;\n\n/** A numeric style-rule literal, including native and JSON-safe bigints. */\nexport const NumericLiteralSchema = z.union([\n z.number(),\n z.bigint(),\n BigintLiteralSchema,\n]);\nexport type NumericLiteral = z.infer<typeof NumericLiteralSchema>;\n\n/**\n * An ISO 8601 or RFC 9557 datetime literal that resolves to a Unix millisecond\n * timestamp at evaluation time. Supported formats:\n * - RFC 9557 with IANA timezone: `\"2024-06-15T14:00:00[Europe/Stockholm]\"` (offset\n * inferred from the named zone, DST-aware) or `\"2024-06-15T14:00:00+02:00[Europe/Stockholm]\"`\n * (offset explicit)\n * - UTC or offset datetime: `\"2024-01-01T00:00:00Z\"`, `\"2024-01-01T00:00:00+02:00\"`\n * - Plain datetime (treated as UTC): `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as UTC midnight): `\"2024-01-01\"`\n */\nexport const DatetimeLiteralSchema = z.object({\n datetime: z.string().refine((s) => parseDateString(s) !== null, {\n message:\n 'datetime must be a valid ISO 8601 / RFC 9557 date or datetime string',\n }),\n});\nexport type DatetimeLiteral = z.infer<typeof DatetimeLiteralSchema>;\n\n/**\n * A plain (unzoned) ISO 8601 date or datetime literal that resolves to a Unix\n * millisecond timestamp at evaluation time, interpreting the wall-clock time\n * in the browser's local timezone.\n *\n * Only plain date/datetime strings without timezone qualifiers are accepted:\n * - Plain datetime: `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as local midnight): `\"2024-01-01\"`\n *\n * Strings with `Z`, a UTC offset (`+02:00`), or an IANA bracket\n * (`[Europe/Stockholm]`) are **rejected** — use `{ datetime }` for\n * timezone-aware instants. This matches the semantics of Neo4j `LocalDateTime`.\n */\nexport const LocalDatetimeLiteralSchema = z.object({\n localdatetime: z.string().refine((s) => parseLocalDateString(s) !== null, {\n message:\n 'localdatetime must be a valid ISO 8601 plain date or datetime string (no Z, offset, or timezone)',\n }),\n});\nexport type LocalDatetimeLiteral = z.infer<typeof LocalDatetimeLiteralSchema>;\n\n/**\n * An ISO 8601 time literal that resolves to milliseconds since UTC midnight\n * at evaluation time. Supported formats:\n * - Local time (treated as UTC): `\"14:30:00\"`, `\"14:30:00.500\"`\n * - UTC time: `\"14:30:00Z\"` — identical to local form\n * - Offset time (UTC-normalised): `\"14:30:00+02:00\"` → 45,000,000 ms (12:30 UTC)\n *\n * IANA timezone brackets (e.g. `[Europe/Stockholm]`) are **not** accepted — a\n * time-of-day value has no calendar date so DST cannot be resolved. Use\n * `{ datetime }` literals for timezone-aware instants.\n *\n * Full datetime strings (containing `T`) are rejected.\n */\nexport const TimeLiteralSchema = z.object({\n time: z.string().refine((s) => parseTimeString(s) !== null, {\n message:\n 'time must be a valid ISO 8601 time string (e.g. \"14:30:00\" or \"14:30:00+02:00\")',\n }),\n});\nexport type TimeLiteral = z.infer<typeof TimeLiteralSchema>;\n"]}
1
+ {"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA2HH,8CAEC;AAGD,wDAIC;AAGD,sCAEC;AAvID;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6BAAwB;AAExB,6CAIsB;AAEtB;;;GAGG;AACU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE;QACrC,OAAO,EAAE,gDAAgD;KAC1D,CAAC;CACH,CAAC,CAAC;AAGH,4EAA4E;AAC/D,QAAA,oBAAoB,GAAG,OAAC,CAAC,KAAK,CAAC;IAC1C,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,2BAAmB;CACpB,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC9D,OAAO,EACL,sEAAsE;KACzE,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iCAAoB,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QACxE,OAAO,EACL,kGAAkG;KACrG,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,EACL,iFAAiF;KACpF,CAAC;CACH,CAAC,CAAC;AAGH,SAAS,qBAAqB,CAC5B,KAAc,EACd,GAAM;IAEN,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,GAAG,IAAI,KAAK;QACZ,OAAQ,KAAiC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAC5D,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,OAAO,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAClD,CAAC;AAED,sGAAsG;AACtG,SAAgB,sBAAsB,CACpC,KAAc;IAEd,OAAO,qBAAqB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC;AAED,6FAA6F;AAC7F,SAAgB,aAAa,CAAC,KAAc;IAC1C,OAAO,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,KAAK,CAAC;IACxC,4BAAoB;IACpB,6BAAqB;IACrB,kCAA0B;IAC1B,yBAAiB;CAClB,CAAC,CAAC","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { z } from 'zod';\n\nimport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\n\n/**\n * A JSON-safe bigint literal. Native bigint values cannot be serialized as\n * JSON, so persisted style rules can use a signed decimal string instead.\n */\nexport const BigintLiteralSchema = z.object({\n bigint: z.string().regex(/^[+-]?\\d+$/, {\n message: 'bigint must be a signed decimal integer string',\n }),\n});\nexport type BigintLiteral = z.infer<typeof BigintLiteralSchema>;\n\n/** A numeric style-rule literal, including native and JSON-safe bigints. */\nexport const NumericLiteralSchema = z.union([\n z.number(),\n z.bigint(),\n BigintLiteralSchema,\n]);\nexport type NumericLiteral = z.infer<typeof NumericLiteralSchema>;\n\n/**\n * An ISO 8601 or RFC 9557 datetime literal that resolves to a Unix millisecond\n * timestamp at evaluation time. Supported formats:\n * - RFC 9557 with IANA timezone: `\"2024-06-15T14:00:00[Europe/Stockholm]\"` (offset\n * inferred from the named zone, DST-aware) or `\"2024-06-15T14:00:00+02:00[Europe/Stockholm]\"`\n * (offset explicit)\n * - UTC or offset datetime: `\"2024-01-01T00:00:00Z\"`, `\"2024-01-01T00:00:00+02:00\"`\n * - Plain datetime (treated as UTC): `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as UTC midnight): `\"2024-01-01\"`\n */\nexport const DatetimeLiteralSchema = z.object({\n datetime: z.string().refine((s) => parseDateString(s) !== null, {\n message:\n 'datetime must be a valid ISO 8601 / RFC 9557 date or datetime string',\n }),\n});\nexport type DatetimeLiteral = z.infer<typeof DatetimeLiteralSchema>;\n\n/**\n * A plain (unzoned) ISO 8601 date or datetime literal that resolves to a Unix\n * millisecond timestamp at evaluation time, interpreting the wall-clock time\n * in the browser's local timezone.\n *\n * Only plain date/datetime strings without timezone qualifiers are accepted:\n * - Plain datetime: `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as local midnight): `\"2024-01-01\"`\n *\n * Strings with `Z`, a UTC offset (`+02:00`), or an IANA bracket\n * (`[Europe/Stockholm]`) are **rejected** — use `{ datetime }` for\n * timezone-aware instants. This matches the semantics of Neo4j `LocalDateTime`.\n */\nexport const LocalDatetimeLiteralSchema = z.object({\n localdatetime: z.string().refine((s) => parseLocalDateString(s) !== null, {\n message:\n 'localdatetime must be a valid ISO 8601 plain date or datetime string (no Z, offset, or timezone)',\n }),\n});\nexport type LocalDatetimeLiteral = z.infer<typeof LocalDatetimeLiteralSchema>;\n\n/**\n * An ISO 8601 time literal that resolves to milliseconds since UTC midnight\n * at evaluation time. Supported formats:\n * - Local time (treated as UTC): `\"14:30:00\"`, `\"14:30:00.500\"`\n * - UTC time: `\"14:30:00Z\"` — identical to local form\n * - Offset time (UTC-normalised): `\"14:30:00+02:00\"` → 45,000,000 ms (12:30 UTC)\n *\n * IANA timezone brackets (e.g. `[Europe/Stockholm]`) are **not** accepted — a\n * time-of-day value has no calendar date so DST cannot be resolved. Use\n * `{ datetime }` literals for timezone-aware instants.\n *\n * Full datetime strings (containing `T`) are rejected.\n */\nexport const TimeLiteralSchema = z.object({\n time: z.string().refine((s) => parseTimeString(s) !== null, {\n message:\n 'time must be a valid ISO 8601 time string (e.g. \"14:30:00\" or \"14:30:00+02:00\")',\n }),\n});\nexport type TimeLiteral = z.infer<typeof TimeLiteralSchema>;\n\nfunction isObjectWithStringKey<K extends string>(\n value: unknown,\n key: K,\n): value is Record<K, string> {\n return (\n typeof value === 'object' &&\n value !== null &&\n key in value &&\n typeof (value as Record<string, unknown>)[key] === 'string'\n );\n}\n\n/** Returns whether a value is a `{ datetime: string }` wrapper. Does not validate the string. */\nexport function isDatetimeLiteral(value: unknown): value is DatetimeLiteral {\n return isObjectWithStringKey(value, 'datetime');\n}\n\n/** Returns whether a value is a `{ localdatetime: string }` wrapper. Does not validate the string. */\nexport function isLocalDatetimeLiteral(\n value: unknown,\n): value is LocalDatetimeLiteral {\n return isObjectWithStringKey(value, 'localdatetime');\n}\n\n/** Returns whether a value is a `{ time: string }` wrapper. Does not validate the string. */\nexport function isTimeLiteral(value: unknown): value is TimeLiteral {\n return isObjectWithStringKey(value, 'time');\n}\n\n/**\n * A continuous, orderable literal that can be used as a range boundary.\n * Temporal literals resolve to numbers before range interpolation.\n */\nexport const RangeLiteralSchema = z.union([\n NumericLiteralSchema,\n DatetimeLiteralSchema,\n LocalDatetimeLiteralSchema,\n TimeLiteralSchema,\n]);\nexport type RangeLiteral = z.infer<typeof RangeLiteralSchema>;\n"]}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /*
3
+ * AUTO-GENERATED FILE — DO NOT EDIT.
4
+ * Source of truth: packages/style-rules/src/
5
+ * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.resolveRangeLiteral = resolveRangeLiteral;
9
+ /**
10
+ *
11
+ * Copyright (c) "Neo4j"
12
+ * Neo4j Sweden AB [http://neo4j.com]
13
+ *
14
+ * This file is part of Neo4j.
15
+ *
16
+ * Neo4j is free software: you can redistribute it and/or modify
17
+ * it under the terms of the GNU General Public License as published by
18
+ * the Free Software Foundation, either version 3 of the License, or
19
+ * (at your option) any later version.
20
+ *
21
+ * This program is distributed in the hope that it will be useful,
22
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ * GNU General Public License for more details.
25
+ *
26
+ * You should have received a copy of the GNU General Public License
27
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ */
29
+ const date_utils_1 = require("./date-utils");
30
+ const numeric_utils_1 = require("./numeric-utils");
31
+ /** Resolves a range literal to the numeric representation used for interpolation. */
32
+ function resolveRangeLiteral(value) {
33
+ if (typeof value === 'object' && value !== null) {
34
+ if ('datetime' in value) {
35
+ return (0, date_utils_1.parseDateString)(value.datetime);
36
+ }
37
+ if ('localdatetime' in value) {
38
+ return (0, date_utils_1.parseLocalDateString)(value.localdatetime);
39
+ }
40
+ if ('time' in value) {
41
+ return (0, date_utils_1.parseTimeString)(value.time);
42
+ }
43
+ }
44
+ return (0, numeric_utils_1.resolveNumericLiteral)(value);
45
+ }
46
+ //# sourceMappingURL=range-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-utils.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/range-utils.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAgCH,kDAaC;AA3CD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6CAIsB;AAEtB,mDAA2E;AAE3E,qFAAqF;AACrF,SAAgB,mBAAmB,CAAC,KAAmB;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,OAAO,IAAA,4BAAe,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YAC7B,OAAO,IAAA,iCAAoB,EAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,IAAA,4BAAe,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,IAAA,qCAAqB,EAAC,KAAK,CAAC,CAAC;AACtC,CAAC","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nimport type { RangeLiteral } from './literal-schemas';\nimport { type NumericValue, resolveNumericLiteral } from './numeric-utils';\n\n/** Resolves a range literal to the numeric representation used for interpolation. */\nexport function resolveRangeLiteral(value: RangeLiteral): NumericValue | null {\n if (typeof value === 'object' && value !== null) {\n if ('datetime' in value) {\n return parseDateString(value.datetime);\n }\n if ('localdatetime' in value) {\n return parseLocalDateString(value.localdatetime);\n }\n if ('time' in value) {\n return parseTimeString(value.time);\n }\n }\n return resolveNumericLiteral(value);\n}\n"]}
package/lib/cjs/index.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
21
  */
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.parseStyleRules = exports.compileGraphStyleRules = exports.isGraphStyleRule = exports.useGraphVisualizationContext = exports.GraphVisualization = void 0;
23
+ exports.parseStyleRules = exports.doesGraphStyleRuleMatch = exports.compileGraphStyleRules = exports.isGraphStyleRule = exports.useGraphVisualizationContext = exports.GraphVisualization = void 0;
24
24
  var graph_visualization_1 = require("./graph-visualization");
25
25
  Object.defineProperty(exports, "GraphVisualization", { enumerable: true, get: function () { return graph_visualization_1.GraphVisualization; } });
26
26
  var graph_visualization_context_1 = require("./graph-visualization-context");
@@ -29,6 +29,7 @@ var style_types_1 = require("./styling/style-types");
29
29
  Object.defineProperty(exports, "isGraphStyleRule", { enumerable: true, get: function () { return style_types_1.isGraphStyleRule; } });
30
30
  var compile_graph_styles_1 = require("./styling/compile-graph-styles");
31
31
  Object.defineProperty(exports, "compileGraphStyleRules", { enumerable: true, get: function () { return compile_graph_styles_1.compileGraphStyleRules; } });
32
+ Object.defineProperty(exports, "doesGraphStyleRuleMatch", { enumerable: true, get: function () { return compile_graph_styles_1.doesGraphStyleRuleMatch; } });
32
33
  var parse_style_rules_1 = require("./styling/parse-style-rules");
33
34
  Object.defineProperty(exports, "parseStyleRules", { enumerable: true, get: function () { return parse_style_rules_1.parseStyleRules; } });
34
35
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAC3B,6EAgBuC;AAfrC,2IAAA,4BAA4B,OAAA;AAgB9B,qDAAyD;AAAhD,+GAAA,gBAAgB,OAAA;AAoBzB,uEAAwE;AAA/D,8HAAA,sBAAsB,OAAA;AAC/B,iEAA8D;AAArD,oHAAA,eAAe,OAAA","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { GraphVisualization } from './graph-visualization';\nexport {\n useGraphVisualizationContext,\n type ColorCount,\n type Gesture,\n type GraphItemMetaData,\n type GraphSelection,\n type GraphVisualizationContextData,\n type InteractionMode,\n type MetadataLookupTable,\n type NeoNode,\n type NeoRel,\n type NodeData,\n type NvlGraph,\n type PortableProperty,\n type RelData,\n type Sidepanel,\n} from './graph-visualization-context';\nexport { isGraphStyleRule } from './styling/style-types';\nexport type {\n GraphStyleRule,\n GraphBigintLiteral,\n GraphNumericLiteral,\n Style as GraphStyle,\n Where as GraphWhere,\n Value as GraphValue,\n CypherValue as GraphCypherValue,\n Caption as GraphCaption,\n CaptionValue as GraphCaptionValue,\n CaptionVariation as GraphCaptionVariation,\n ColorRange as GraphColorRange,\n SizeRange as GraphSizeRange,\n WidthRange as GraphWidthRange,\n UniqueColors as GraphUniqueColors,\n DatetimeLiteral as GraphDatetimeLiteral,\n LocalDatetimeLiteral as GraphLocalDatetimeLiteral,\n TimeLiteral as GraphTimeLiteral,\n} from './styling/style-types';\nexport { compileGraphStyleRules } from './styling/compile-graph-styles';\nexport { parseStyleRules } from './styling/parse-style-rules';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAC3B,6EAgBuC;AAfrC,2IAAA,4BAA4B,OAAA;AAgB9B,qDAAyD;AAAhD,+GAAA,gBAAgB,OAAA;AAqBzB,uEAGwC;AAFtC,8HAAA,sBAAsB,OAAA;AACtB,+HAAA,uBAAuB,OAAA;AAEzB,iEAA8D;AAArD,oHAAA,eAAe,OAAA","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { GraphVisualization } from './graph-visualization';\nexport {\n useGraphVisualizationContext,\n type ColorCount,\n type Gesture,\n type GraphItemMetaData,\n type GraphSelection,\n type GraphVisualizationContextData,\n type InteractionMode,\n type MetadataLookupTable,\n type NeoNode,\n type NeoRel,\n type NodeData,\n type NvlGraph,\n type PortableProperty,\n type RelData,\n type Sidepanel,\n} from './graph-visualization-context';\nexport { isGraphStyleRule } from './styling/style-types';\nexport type {\n GraphStyleRule,\n GraphBigintLiteral,\n GraphNumericLiteral,\n GraphRangeLiteral,\n Style as GraphStyle,\n Where as GraphWhere,\n Value as GraphValue,\n CypherValue as GraphCypherValue,\n Caption as GraphCaption,\n CaptionValue as GraphCaptionValue,\n CaptionVariation as GraphCaptionVariation,\n ColorRange as GraphColorRange,\n SizeRange as GraphSizeRange,\n WidthRange as GraphWidthRange,\n UniqueColors as GraphUniqueColors,\n DatetimeLiteral as GraphDatetimeLiteral,\n LocalDatetimeLiteral as GraphLocalDatetimeLiteral,\n TimeLiteral as GraphTimeLiteral,\n} from './styling/style-types';\nexport {\n compileGraphStyleRules,\n doesGraphStyleRuleMatch,\n} from './styling/compile-graph-styles';\nexport { parseStyleRules } from './styling/parse-style-rules';\n"]}
@@ -32,6 +32,7 @@ var __rest = (this && this.__rest) || function (s, e) {
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  exports.UNIQUE_COLORS_PALETTE = exports.DEFAULT_REL_COLOR = void 0;
35
+ exports.doesGraphStyleRuleMatch = doesGraphStyleRuleMatch;
35
36
  exports.compileGraphStyleRules = compileGraphStyleRules;
36
37
  const word_color_1 = require("@neo4j-devtools/word-color");
37
38
  const base_1 = require("@neo4j-ndl/base");
@@ -113,8 +114,11 @@ function getInterpolatedColor(colorRange, graphItem) {
113
114
  }
114
115
  const minRgb = (0, react_color_1.color)(minColor).rgb;
115
116
  const maxRgb = (0, react_color_1.color)(maxColor).rgb;
116
- const resolvedMinValue = (0, style_rules_1.resolveNumericLiteral)(minValue);
117
- const resolvedMaxValue = (0, style_rules_1.resolveNumericLiteral)(maxValue);
117
+ const resolvedMinValue = (0, style_rules_1.resolveRangeLiteral)(minValue);
118
+ const resolvedMaxValue = (0, style_rules_1.resolveRangeLiteral)(maxValue);
119
+ if (resolvedMinValue === null || resolvedMaxValue === null) {
120
+ return null;
121
+ }
118
122
  const boundsOrder = (0, style_rules_1.compareNumericValues)(resolvedMinValue, resolvedMaxValue);
119
123
  if (boundsOrder === null) {
120
124
  return null;
@@ -123,7 +127,10 @@ function getInterpolatedColor(colorRange, graphItem) {
123
127
  const actualMaxValue = boundsOrder <= 0 ? resolvedMaxValue : resolvedMinValue;
124
128
  // Validate mid stop if provided
125
129
  let midRgb = undefined;
126
- const resolvedMidValue = midValue === undefined ? undefined : (0, style_rules_1.resolveNumericLiteral)(midValue);
130
+ const resolvedMidValue = midValue === undefined ? undefined : (0, style_rules_1.resolveRangeLiteral)(midValue);
131
+ if (resolvedMidValue === null) {
132
+ return null;
133
+ }
127
134
  if (midValue !== undefined && midColor !== undefined) {
128
135
  const minToMid = (0, style_rules_1.compareNumericValues)(actualMinValue, resolvedMidValue);
129
136
  const midToMax = (0, style_rules_1.compareNumericValues)(resolvedMidValue, actualMaxValue);
@@ -184,8 +191,11 @@ function getInterpolatedSize(prop, minValue, maxValue, minOut, maxOut) {
184
191
  if (typeof rawValue !== 'number' && typeof rawValue !== 'bigint') {
185
192
  return null;
186
193
  }
187
- const resolvedMinValue = (0, style_rules_1.resolveNumericLiteral)(minValue);
188
- const resolvedMaxValue = (0, style_rules_1.resolveNumericLiteral)(maxValue);
194
+ const resolvedMinValue = (0, style_rules_1.resolveRangeLiteral)(minValue);
195
+ const resolvedMaxValue = (0, style_rules_1.resolveRangeLiteral)(maxValue);
196
+ if (resolvedMinValue === null || resolvedMaxValue === null) {
197
+ return null;
198
+ }
189
199
  const clampedValue = (0, style_rules_1.clampNumericValue)(rawValue, resolvedMinValue, resolvedMaxValue);
190
200
  if (clampedValue === null) {
191
201
  return null;
@@ -368,6 +378,43 @@ function evaluateWhere(node, where) {
368
378
  }
369
379
  return false;
370
380
  }
381
+ /**
382
+ * Returns whether a graph item is targeted by a single style rule.
383
+ *
384
+ * This evaluates both the rule's node label or relationship type selector and
385
+ * its optional `where` clause. Disabled rules never match. Cypher-style
386
+ * three-valued logic is reduced to a boolean: only `true` matches, while
387
+ * `false` and `null` do not.
388
+ *
389
+ * Use {@link compileGraphStyleRules} to evaluate the final style produced by a
390
+ * cascade of rules.
391
+ */
392
+ function doesGraphStyleRuleMatch(item, rule) {
393
+ if (rule.isDisabled === true) {
394
+ return false;
395
+ }
396
+ if ('label' in rule.match) {
397
+ if (!('labelsSorted' in item)) {
398
+ return false;
399
+ }
400
+ if (rule.match.label !== null &&
401
+ !item.labelsSorted.includes(rule.match.label)) {
402
+ return false;
403
+ }
404
+ }
405
+ else if ('reltype' in rule.match) {
406
+ if (!('type' in item)) {
407
+ return false;
408
+ }
409
+ if (rule.match.reltype !== null && item.type !== rule.match.reltype) {
410
+ return false;
411
+ }
412
+ }
413
+ else {
414
+ return false;
415
+ }
416
+ return evaluateWhere(item, rule.where) === true;
417
+ }
371
418
  /**
372
419
  * Resolves a color for the given property value, using the uniqueColors object
373
420
  * reference as the per-rule key in uniqueColorsCache. Assigns a new palette color
@@ -629,16 +676,10 @@ function createRelStyleFunction(rules) {
629
676
  const uniqueColorsCache = new Map();
630
677
  return (rel) => {
631
678
  const style = {};
632
- // evaluateWhere uses Cypher-style three-valued logic (true/false/null).
633
- // Only `true` passes; both `false` and `null` (unknown) skip the rule.
634
679
  for (const rule of rules) {
635
- // Check if the rule applies to this relationship
636
- if ('reltype' in rule.match) {
637
- const isReltypeMatch = rule.match.reltype === null || rel.type === rule.match.reltype;
638
- if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {
639
- // Merge the style properties (later rules override earlier ones)
640
- Object.assign(style, rule.apply);
641
- }
680
+ if (doesGraphStyleRuleMatch(rel, rule)) {
681
+ // Merge the style properties (later rules override earlier ones)
682
+ Object.assign(style, rule.apply);
642
683
  }
643
684
  }
644
685
  return evaluateRelStyle(style, rel, uniqueColorsCache);
@@ -695,8 +736,7 @@ function createByLabelSetFunction(styleMatchers) {
695
736
  if (rule.where !== undefined || rule.apply.uniqueColors !== undefined) {
696
737
  isCacheable = false;
697
738
  }
698
- const shouldApplyRule = rule.where === undefined || evaluateWhere(node, rule.where) === true;
699
- if (shouldApplyRule) {
739
+ if (doesGraphStyleRuleMatch(node, rule)) {
700
740
  Object.assign(collectStyles, rule.apply);
701
741
  }
702
742
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;;;;;;;;;AA+7BH,wDA2BC;AAx9BD,2DAAwE;AACxE,0CAAyC;AACzC,kDAA4E;AAE5E,2DAYmC;AAmBtB,QAAA,iBAAiB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9D,MAAM,uBAAuB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD,QAAA,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,aAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CACrE,sBAAQ,CACT,CAAC;AASF,SAAS,0BAA0B,CACjC,CAAiB,EACjB,CAAiB;IAEjB,OAAO,CAAC,CAAC,QAAS,GAAG,CAAC,CAAC,QAAS,CAAC;AACnC,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAA2C;IAE3C,MAAM,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;IACxD,MAAM,gBAAgB,GAAqB,EAAE,CAAC;IAC9C,MAAM,kBAAkB,GAAqB,EAAE,CAAC;IAEhD,0CAA0C;IAC1C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,gBAAgB;YAChB,kBAAkB;YAClB,YAAY;YACZ,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAEjC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;;QAC9B,IAAI,MAAA,KAAK,CAAC,UAAU,mCAAI,KAAK,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,6CAA6C,KAAK,CAAC,QAAQ,kDAAkD,CAC9G,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,MAAM,EAAE,QAAQ,KAAc,KAAK,EAAd,IAAI,UAAK,KAAK,EAA7B,YAAqB,CAAQ,CAAC;QACpC,MAAM,gBAAgB,mCACjB,IAAI,KACP,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK,GAAG,UAAU,GACzC,CAAC;QAEF,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,8DAA8D;YAC9D,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC/B,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,sBAAsB;gBACtB,MAAM,QAAQ,GAAG,MAAA,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC;gBAC3D,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACjC,iDAAiD;gBACjD,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,wBAAwB;gBACxB,MAAM,QAAQ,GAAG,MAAA,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,mCAAI,EAAE,CAAC;gBAC5D,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,kBAAkB;QAClB,YAAY;QACZ,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAC3B,UAAsB,EACtB,SAA6B;IAE7B,MAAM,EACJ,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,GAAG,UAAU,CAAC;IAEf,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IACnC,MAAM,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IACnC,MAAM,gBAAgB,GAAG,IAAA,mCAAqB,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,IAAA,mCAAqB,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,IAAA,kCAAoB,EAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAC7E,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,cAAc,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC9E,MAAM,cAAc,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAE9E,gCAAgC;IAChC,IAAI,MAAM,GAAyB,SAAS,CAAC;IAC7C,MAAM,gBAAgB,GACpB,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,mCAAqB,EAAC,QAAQ,CAAC,CAAC;IACvE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAA,kCAAoB,EAAC,cAAc,EAAE,gBAAiB,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAA,kCAAoB,EAAC,gBAAiB,EAAE,cAAc,CAAC,CAAC;QACzE,MAAM,YAAY,GAChB,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,IAAA,+BAAiB,EACpC,QAAQ,EACR,cAAc,EACd,cAAc,CACf,CAAC;IACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAa,CAAC;IAElB,IAAI,MAAM,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,CAAC;QACvC,IAAI,kBAAkB,EAAE,CAAC;YACvB,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,IAAA,8BAAgB,EACnC,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;YACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAA,sBAAQ,EAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,IAAkC,EAClC,QAAwB,EACxB,QAAwB,EACxB,MAAc,EACd,MAAc;IAEd,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAA,mCAAqB,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,IAAA,mCAAqB,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,IAAA,+BAAiB,EACpC,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,CACjB,CAAC;IACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;IACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;AACjD,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAsB;IAEtB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC5C,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAY;oBAC1C,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBACrB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YAAC,WAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,+DAA+D;QAC/D,4EAA4E;QAC5E,0EAA0E;QAC1E,+CAA+C;QAC/C,EAAE;QACF,0DAA0D;QAC1D,4EAA4E;QAC5E,KAAK,UAAU,CAAC;QAChB,KAAK,eAAe,CAAC;QACrB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAW,CAAC;YACjD,OAAO,IAAA,6BAAe,EAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,kEAAkE;QAClE,2CAA2C;QAC3C,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAW,CAAC;YACjD,OAAO,IAAA,6BAAe,EAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD;YACE,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;AACH,CAAC;AAaD;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa,CAAC,IAAwB,EAAE,KAAa;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;QAClC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,2CAA2C;QAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC;YAC5D,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,CAAC,EAC9D,CAAC;YACD,OAAO,IAAA,gCAAkB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,OAAO,KAAK,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,0BAA0B;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5C,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,iBAAiB,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;QAC5C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,aAAa,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QACxC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QACvC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACtB,0CAA0C;QAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,KAAK,KAAK,IAAI,CAAC;IACxB,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,2BAA2B;QAC3B,4BAA4B;QAC5B,+BAA+B;QAC/B,gBAAgB;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QAClB,0BAA0B;QAC1B,0BAA0B;QAC1B,+BAA+B;QAC/B,iBAAiB;QACjB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,IAAK,IAAgB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAAC;QAC5E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC;IACtE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CACzB,YAA0B,EAC1B,UAAwD,EACxD,iBAAyD;IAEzD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElC,IAAI,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QACrB,iBAAiB,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,aAAa;YACX,6BAAqB,CAAC,QAAQ,CAAC,IAAI,GAAG,6BAAqB,CAAC,MAAM,CAAE,CAAC;QACvE,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,iBAAiB,CACxB,IAA0C;IAE1C,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,EAGE;QAHF,EAC3B,WAAW,OAEkB,EAD1B,WAAW,cAFa,eAG5B,CADe;IAEd,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACtD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,MAAW,gBAAgB,UAAK,WAAY,EAAtC,EAAuB,CAAe,CAAC;QAC7C,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACxC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAY,EACZ,GAAY,EACZ,iBAAyD;IAEzD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,KACpD,KAAK,EADoD,WAAW,UACpE,KAAK,EADD,wDAAkE,CACjE,CAAC;IACR,MAAM,MAAM,GACV,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEnC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAS,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,CAAC,QAAQ,GAAG,QAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YACrC,CAAC;YAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;oBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YAC1C,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,oBAAoB,CAAC,UAAW,EAAE,GAAG,CAAC,CAAC;QAC5D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,UAAW,CAAC;QAC3E,MAAM,YAAY,GAAG,mBAAmB,CACtC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,CACT,CAAC;QACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,kBAAkB,CAC9B,YAAa,EACb,GAAG,CAAC,UAAU,EACd,iBAAiB,CAClB,CAAC;QACF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAClB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAGY;IAEZ,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAA4C;IAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,mEAAmE;IACnE,IACE,OAAO,KAAK,IAAI;QAChB,QAAQ,KAAK,IAAI;QACjB,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,QAAQ,KAAK,QAAQ,EAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CACpB,KAAY,EACZ,SAA6B;IAE7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,IAAI,cAAc,IAAI,SAAS,EAAE,CAAC;gBAChC,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CACrE,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,OAAO,CACL,KAAK,CAAC,OAAO,KAAK,IAAI;oBACrB,SAAqB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAC9C,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,OAAO,IAAA,6BAAe,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YAC7B,OAAO,IAAA,kCAAoB,EAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,IAAA,6BAAe,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,IAAA,6BAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAA,mCAAqB,EAAC,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,KAA4B,CAAC;AACtC,CAAC;AAED,kCAAkC;AAClC,MAAM,oBAAoB,GAAG;IAC3B,SAAS;IACT,UAAU;IACV,UAAU;IACV,QAAQ;IACR,eAAe;IACf,KAAK;CACN,CAAC;AAEF,SAAS,qBAAqB,CAAC,IAAc;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAElD,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAY,EACZ,IAAc,EACd,iBAAyD;IAEzD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,KACnD,KAAK,EADmD,WAAW,UACnE,KAAK,EADD,uDAAiE,CAChE,CAAC;IACR,MAAM,MAAM,GAA0B,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEvE,MAAM,aAAa,GACjB,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAS,CAAC,IAAI;QAC3C,CAAC,CAAC,QAAS,CAAC,IAAI;QAChB,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpC,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC;QAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC/B,CAAC;YAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;gBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QAC1C,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,oBAAoB,CAAC,UAAW,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,SAAU,CAAC;QACxE,MAAM,YAAY,GAAG,mBAAmB,CACtC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,CACR,CAAC;QACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,kBAAkB,CAC9B,YAAa,EACb,IAAI,CAAC,UAAU,EACf,iBAAiB,CAClB,CAAC;QACF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAuB;IAEvB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAqC,CAAC;IACvE,OAAO,CAAC,GAAY,EAAE,EAAE;QACtB,MAAM,KAAK,GAAU,EAAE,CAAC;QAExB,wEAAwE;QACxE,uEAAuE;QACvE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,iDAAiD;YACjD,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5B,MAAM,cAAc,GAClB,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;gBAEjE,IAAI,cAAc,IAAI,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC9D,iEAAiE;oBACjE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC;AAQD,SAAS,wBAAwB,CAC/B,aAA4B;IAE5B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC7D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiB,CAAC;IAClD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAqC,CAAC;IAEvE,OAAO,CAAC,IAAc,EAAE,EAAE;;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjD,yEAAyE;QACzE,mFAAmF;QACnF,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,iBAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACjE,CAAC;QAED,uCAAuC;QACvC,MAAM,oBAAoB,GAAG,MAAA,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;QAC1D,IAAI,YAAoB,CAAC;QACzB,IAAI,oBAAoB,KAAK,IAAI,EAAE,CAAC;YAClC,YAAY,GAAG,uBAAuB,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACzD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM;oBACJ,IAAA,uCAA0B,EAAC,oBAAoB,CAAC,CAAC,eAAe,CAAC;gBACnE,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,YAAY,GAAG,MAAM,CAAC;QACxB,CAAC;QAED,sEAAsE;QACtE,IAAI,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAqB;gBACtC,GAAG,aAAa,CAAC,gBAAgB;aAClC,CAAC;YACF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,UAAU,EAAE,CAAC;oBACf,aAAa,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YACjE,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;QAED,6EAA6E;QAC7E,MAAM,aAAa,GAAU,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC;QAChE,IAAI,WAAW,GAAG,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACtE,WAAW,GAAG,KAAK,CAAC;YACtB,CAAC;YACD,MAAM,eAAe,GACnB,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;YACvE,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,2BAA2B;QAC3B,IAAI,WAAW,EAAE,CAAC;YAChB,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,iBAAiB,CAAC,aAAa,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAmB;IACxC,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE;QAClD,KAAK,EAAE,EAAE,KAAK,EAAE,yBAAiB,EAAE;KACpC;IACD,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;CACzB,CAAC;AAEF,SAAgB,sBAAsB,CACpC,UAA+C;IAE/C,MAAM,aAAa,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAEvD,gEAAgE;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAGlB,CAAC;IACJ,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;;QAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,MAAA,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC;YACxD,EAAE,GAAG,sBAAsB,CAAC;gBAC1B,iBAAiB;gBACjB,GAAG,aAAa,CAAC,kBAAkB;gBACnC,GAAG,KAAK;aACT,CAAC,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\nimport { color, type RgbColor, rgbToHex, validHex } from '@uiw/react-color';\n\nimport {\n clampNumericValue,\n compareNumericValues,\n getNumericWeight,\n isBigintLiteral,\n lerpColor,\n type NumericLiteral,\n numericValuesEqual,\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n resolveNumericLiteral,\n} from '../_generated/style-rules';\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport {\n type Caption,\n type ColorRange,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type GraphStyleRule,\n type NonStaticStyles,\n type Style,\n type UniqueColors,\n type Value,\n type Where,\n} from './style-types';\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nexport const UNIQUE_COLORS_PALETTE = Object.values(tokens.graph).filter(\n validHex,\n);\n\ntype StyleMatchers = {\n globalLabelRules: GraphStyleRule[];\n globalReltypeRules: GraphStyleRule[];\n rulesByLabel: Map<string, GraphStyleRule[]>;\n rulesByType: Map<string, GraphStyleRule[]>;\n};\n\nfunction compareByPriorityAscending(\n a: GraphStyleRule,\n b: GraphStyleRule,\n): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: GraphStyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, GraphStyleRule[]>();\n const rulesByType = new Map<string, GraphStyleRule[]>();\n const globalLabelRules: GraphStyleRule[] = [];\n const globalReltypeRules: GraphStyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.isDisabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `GraphStyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: GraphStyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\n/**\n * Interpolates a color from a ColorRange based on a graph item's property value.\n * Returns a #rrggbb hex string, or null if the colorRange config is invalid\n * (bad hex colors, invalid value range, missing/non-numeric property).\n */\nfunction getInterpolatedColor(\n colorRange: ColorRange,\n graphItem: NodeData | RelData,\n): string | null {\n const {\n onProperty,\n minValue,\n minColor,\n maxValue,\n maxColor,\n midValue,\n midColor,\n } = colorRange;\n\n if (!validHex(minColor) || !validHex(maxColor)) {\n return null;\n }\n const minRgb = color(minColor).rgb;\n const maxRgb = color(maxColor).rgb;\n const resolvedMinValue = resolveNumericLiteral(minValue);\n const resolvedMaxValue = resolveNumericLiteral(maxValue);\n const boundsOrder = compareNumericValues(resolvedMinValue, resolvedMaxValue);\n if (boundsOrder === null) {\n return null;\n }\n const actualMinValue = boundsOrder <= 0 ? resolvedMinValue : resolvedMaxValue;\n const actualMaxValue = boundsOrder <= 0 ? resolvedMaxValue : resolvedMinValue;\n\n // Validate mid stop if provided\n let midRgb: RgbColor | undefined = undefined;\n const resolvedMidValue =\n midValue === undefined ? undefined : resolveNumericLiteral(midValue);\n if (midValue !== undefined && midColor !== undefined) {\n const minToMid = compareNumericValues(actualMinValue, resolvedMidValue!);\n const midToMax = compareNumericValues(resolvedMidValue!, actualMaxValue);\n const isMidInRange =\n minToMid !== null && midToMax !== null && minToMid <= 0 && midToMax <= 0;\n if (!isMidInRange || !validHex(midColor)) {\n return null;\n }\n midRgb = color(midColor).rgb;\n }\n\n const prop = graphItem.properties[onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number' && typeof rawValue !== 'bigint') {\n return null;\n }\n\n const clampedValue = clampNumericValue(\n rawValue,\n actualMinValue,\n actualMaxValue,\n );\n if (clampedValue === null) {\n return null;\n }\n\n let rgb: RgbColor;\n\n if (midRgb !== undefined && resolvedMidValue !== undefined) {\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMidValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n const isBetweenMinAndMid = weight <= 1;\n if (isBetweenMinAndMid) {\n rgb = lerpColor(minRgb, midRgb, weight);\n } else {\n const secondWeight = getNumericWeight(\n resolvedMidValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (secondWeight === null) {\n return null;\n }\n rgb = lerpColor(midRgb, maxRgb, secondWeight);\n }\n } else {\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n rgb = lerpColor(minRgb, maxRgb, weight);\n }\n\n return rgbToHex(rgb);\n}\n\n/**\n * Interpolates a numeric size/width from a range based on a graph item's property value.\n * Returns the interpolated number, or null if the property is missing or non-numeric.\n */\nfunction getInterpolatedSize(\n prop: PortableProperty | undefined,\n minValue: NumericLiteral,\n maxValue: NumericLiteral,\n minOut: number,\n maxOut: number,\n): number | null {\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number' && typeof rawValue !== 'bigint') {\n return null;\n }\n\n const resolvedMinValue = resolveNumericLiteral(minValue);\n const resolvedMaxValue = resolveNumericLiteral(maxValue);\n const clampedValue = clampNumericValue(\n rawValue,\n resolvedMinValue,\n resolvedMaxValue,\n );\n if (clampedValue === null) {\n return null;\n }\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n return minOut * (1 - weight) + maxOut * weight;\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | bigint | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'Integer':\n case 'float':\n return Number(prop.stringified);\n case 'bigint':\n case 'BigInt': {\n try {\n const value = prop.stringified.startsWith('\"')\n ? (JSON.parse(prop.stringified) as string)\n : prop.stringified;\n return BigInt(value);\n } catch {\n return null;\n }\n }\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n // Neo4j temporal types — parse to a number for comparison with\n // { datetime } and { time } rule literals. An unparseable value resolves to\n // null (treated as missing) rather than leaking a raw string into numeric\n // comparisons, matching Cypher null semantics.\n //\n // DateTime / LocalDateTime → Unix milliseconds (epoch ms)\n // LocalDateTime has no timezone; treated as UTC, same as date-only strings.\n case 'DateTime':\n case 'LocalDateTime':\n case 'Date': {\n const s = JSON.parse(prop.stringified) as string;\n return parseDateString(s);\n }\n // Time (ZonedTime) / LocalTime → UTC-normalised ms since midnight\n // LocalTime has no offset; treated as UTC.\n case 'Time':\n case 'LocalTime': {\n const s = JSON.parse(prop.stringified) as string;\n return parseTimeString(s);\n }\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\ntype ResolvedCypherValue = string | number | bigint | boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n if (\n (typeof leftVal === 'number' || typeof leftVal === 'bigint') &&\n (typeof rightVal === 'number' || typeof rightVal === 'bigint')\n ) {\n return numericValuesEqual(leftVal, rightVal);\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\n/**\n * Resolves a color for the given property value, using the uniqueColors object\n * reference as the per-rule key in uniqueColorsCache. Assigns a new palette color\n * on first encounter (first-come, first-served). Returns null if the property is\n * missing or null.\n */\nfunction resolveUniqueColor(\n uniqueColors: UniqueColors,\n properties: Record<string, PortableProperty | undefined>,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): string | null {\n const prop = properties[uniqueColors.onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (rawValue === null) {\n return null;\n }\n const valueKey = String(rawValue);\n\n let valueMap = uniqueColorsCache.get(uniqueColors);\n if (valueMap === undefined) {\n valueMap = new Map();\n uniqueColorsCache.set(uniqueColors, valueMap);\n }\n\n let assignedColor = valueMap.get(valueKey);\n if (assignedColor === undefined) {\n assignedColor =\n UNIQUE_COLORS_PALETTE[valueMap.size % UNIQUE_COLORS_PALETTE.length]!;\n valueMap.set(valueKey, assignedColor);\n }\n\n return assignedColor;\n}\n\nfunction shouldUseProperty(\n prop: { isDisabled?: boolean } | undefined,\n): boolean {\n return prop !== undefined && prop.isDisabled !== true;\n}\n\nfunction evaluateStaticStyle({\n overlayIcon,\n ...scalarStyle\n}: Omit<Style, NonStaticStyles>) {\n const result: Record<string, unknown> = {};\n\n for (const [key, prop] of Object.entries(scalarStyle)) {\n if (shouldUseProperty(prop)) {\n result[key] = prop.value;\n }\n }\n\n if (shouldUseProperty(overlayIcon)) {\n const { ...overlayIconProps } = overlayIcon!;\n result.overlayIcon = overlayIconProps;\n }\n\n return result;\n}\n\nfunction evaluateRelStyle(\n style: Style,\n rel: RelData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlRelationshipStyle {\n const { captions, colorRange, widthRange, uniqueColors, ...staticStyle } =\n style;\n const result: EvaluatedNvlRelationshipStyle =\n evaluateStaticStyle(staticStyle);\n\n if (shouldUseProperty(captions) && captions!.text) {\n result.captions = captions!.text.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n });\n\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, rel);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(widthRange)) {\n const { onProperty, minValue, maxValue, minWidth, maxWidth } = widthRange!;\n const interpolated = getInterpolatedSize(\n rel.properties[onProperty],\n minValue,\n maxValue,\n minWidth,\n maxWidth,\n );\n if (interpolated !== null) {\n result.width = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n rel.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<ResolvedCypherValue>,\n b: NonNullable<ResolvedCypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): ResolvedCypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n if ('datetime' in value) {\n return parseDateString(value.datetime);\n }\n if ('localdatetime' in value) {\n return parseLocalDateString(value.localdatetime);\n }\n if ('time' in value) {\n return parseTimeString(value.time);\n }\n if (isBigintLiteral(value)) {\n return resolveNumericLiteral(value);\n }\n }\n\n return value as ResolvedCypherValue;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n style: Style,\n node: NodeData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlNodeStyle {\n const { captions, colorRange, sizeRange, uniqueColors, ...staticStyle } =\n style;\n const result: EvaluatedNvlNodeStyle = evaluateStaticStyle(staticStyle);\n\n const captionSource =\n shouldUseProperty(captions) && captions!.text\n ? captions!.text\n : [getDefaultNodeCaption(node)];\n\n result.captions = captionSource.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n });\n\n if (shouldUseProperty(captions)) {\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, node);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(sizeRange)) {\n const { onProperty, minValue, maxValue, minSize, maxSize } = sizeRange!;\n const interpolated = getInterpolatedSize(\n node.properties[onProperty],\n minValue,\n maxValue,\n minSize,\n maxSize,\n );\n if (interpolated !== null) {\n result.size = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n node.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\nfunction createRelStyleFunction(\n rules: GraphStyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n return (rel: RelData) => {\n const style: Style = {};\n\n // evaluateWhere uses Cypher-style three-valued logic (true/false/null).\n // Only `true` passes; both `false` and `null` (unknown) skip the rule.\n for (const rule of rules) {\n // Check if the rule applies to this relationship\n if ('reltype' in rule.match) {\n const isReltypeMatch =\n rule.match.reltype === null || rel.type === rule.match.reltype;\n\n if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n }\n\n return evaluateRelStyle(style, rel, uniqueColorsCache);\n };\n}\n\nexport type CompiledGraphStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, GraphStyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free and none use\n // uniqueColors, the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node, uniqueColorsCache);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: GraphStyleRule[] = [\n ...styleMatchers.globalLabelRules,\n ];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free and uniqueColors-free.\n const collectStyles: Style = { color: { value: defaultColor } };\n let isCacheable = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined || rule.apply.uniqueColors !== undefined) {\n isCacheable = false;\n }\n const shouldApplyRule =\n rule.where === undefined || evaluateWhere(node, rule.where) === true;\n if (shouldApplyRule) {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free and uniqueColors-free, the merged style\n // depends only on labels. Cache it so subsequent nodes with the same label\n // set skip rule iteration.\n if (isCacheable) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node, uniqueColorsCache);\n };\n}\n\nconst DEFAULT_REL_STYLE: GraphStyleRule = {\n apply: {\n captions: { text: [{ value: { useType: true } }] },\n color: { value: DEFAULT_REL_COLOR },\n },\n match: { reltype: null },\n};\n\nexport function compileGraphStyleRules(\n styleRules: GraphStyleRule[] | null | undefined,\n): CompiledGraphStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}
1
+ {"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;;;;;;;;;AAofH,0DA8BC;AAwdD,wDA2BC;AAngCD,2DAAwE;AACxE,0CAAyC;AACzC,kDAA4E;AAE5E,2DAamC;AAmBtB,QAAA,iBAAiB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9D,MAAM,uBAAuB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD,QAAA,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,aAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CACrE,sBAAQ,CACT,CAAC;AASF,SAAS,0BAA0B,CACjC,CAAiB,EACjB,CAAiB;IAEjB,OAAO,CAAC,CAAC,QAAS,GAAG,CAAC,CAAC,QAAS,CAAC;AACnC,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAA2C;IAE3C,MAAM,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;IACxD,MAAM,gBAAgB,GAAqB,EAAE,CAAC;IAC9C,MAAM,kBAAkB,GAAqB,EAAE,CAAC;IAEhD,0CAA0C;IAC1C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,gBAAgB;YAChB,kBAAkB;YAClB,YAAY;YACZ,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAEjC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;;QAC9B,IAAI,MAAA,KAAK,CAAC,UAAU,mCAAI,KAAK,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,6CAA6C,KAAK,CAAC,QAAQ,kDAAkD,CAC9G,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,MAAM,EAAE,QAAQ,KAAc,KAAK,EAAd,IAAI,UAAK,KAAK,EAA7B,YAAqB,CAAQ,CAAC;QACpC,MAAM,gBAAgB,mCACjB,IAAI,KACP,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK,GAAG,UAAU,GACzC,CAAC;QAEF,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,8DAA8D;YAC9D,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC/B,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,sBAAsB;gBACtB,MAAM,QAAQ,GAAG,MAAA,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC;gBAC3D,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACjC,iDAAiD;gBACjD,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,wBAAwB;gBACxB,MAAM,QAAQ,GAAG,MAAA,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,mCAAI,EAAE,CAAC;gBAC5D,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,kBAAkB;QAClB,YAAY;QACZ,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAC3B,UAAsB,EACtB,SAA6B;IAE7B,MAAM,EACJ,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,GAAG,UAAU,CAAC;IAEf,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IACnC,MAAM,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IACnC,MAAM,gBAAgB,GAAG,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,WAAW,GAAG,IAAA,kCAAoB,EAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAC7E,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,cAAc,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC9E,MAAM,cAAc,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAE9E,gCAAgC;IAChC,IAAI,MAAM,GAAyB,SAAS,CAAC;IAC7C,MAAM,gBAAgB,GACpB,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAA,kCAAoB,EAAC,cAAc,EAAE,gBAAiB,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAA,kCAAoB,EAAC,gBAAiB,EAAE,cAAc,CAAC,CAAC;QACzE,MAAM,YAAY,GAChB,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,IAAI,CAAC,IAAA,sBAAQ,EAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,IAAA,mBAAK,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,IAAA,+BAAiB,EACpC,QAAQ,EACR,cAAc,EACd,cAAc,CACf,CAAC;IACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAa,CAAC;IAElB,IAAI,MAAM,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,CAAC;QACvC,IAAI,kBAAkB,EAAE,CAAC;YACvB,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,IAAA,8BAAgB,EACnC,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;YACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,GAAG,IAAA,uBAAS,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAA,sBAAQ,EAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,IAAkC,EAClC,QAAsB,EACtB,QAAsB,EACtB,MAAc,EACd,MAAc;IAEd,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,IAAA,+BAAiB,EACpC,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,CACjB,CAAC;IACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,8BAAgB,EAC7B,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,CACb,CAAC;IACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;AACjD,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAsB;IAEtB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC5C,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAY;oBAC1C,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBACrB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YAAC,WAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,+DAA+D;QAC/D,4EAA4E;QAC5E,0EAA0E;QAC1E,+CAA+C;QAC/C,EAAE;QACF,0DAA0D;QAC1D,4EAA4E;QAC5E,KAAK,UAAU,CAAC;QAChB,KAAK,eAAe,CAAC;QACrB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAW,CAAC;YACjD,OAAO,IAAA,6BAAe,EAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,kEAAkE;QAClE,2CAA2C;QAC3C,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAW,CAAC;YACjD,OAAO,IAAA,6BAAe,EAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD;YACE,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;AACH,CAAC;AAaD;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa,CAAC,IAAwB,EAAE,KAAa;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;QAClC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,2CAA2C;QAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC;YAC5D,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,CAAC,EAC9D,CAAC;YACD,OAAO,IAAA,gCAAkB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,OAAO,KAAK,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,0BAA0B;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5C,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,iBAAiB,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;QAC5C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,aAAa,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QACxC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QACvC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACtB,0CAA0C;QAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,KAAK,KAAK,IAAI,CAAC;IACxB,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,2BAA2B;QAC3B,4BAA4B;QAC5B,+BAA+B;QAC/B,gBAAgB;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QAClB,0BAA0B;QAC1B,0BAA0B;QAC1B,+BAA+B;QAC/B,iBAAiB;QACjB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,IAAK,IAAgB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAAC;QAC5E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC;IACtE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,uBAAuB,CACrC,IAAwB,EACxB,IAAoB;IAEpB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,cAAc,IAAI,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IACE,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI;YACzB,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAC7C,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;SAAM,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CACzB,YAA0B,EAC1B,UAAwD,EACxD,iBAAyD;IAEzD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElC,IAAI,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QACrB,iBAAiB,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,aAAa;YACX,6BAAqB,CAAC,QAAQ,CAAC,IAAI,GAAG,6BAAqB,CAAC,MAAM,CAAE,CAAC;QACvE,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,iBAAiB,CACxB,IAA0C;IAE1C,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,EAGE;QAHF,EAC3B,WAAW,OAEkB,EAD1B,WAAW,cAFa,eAG5B,CADe;IAEd,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACtD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,MAAW,gBAAgB,UAAK,WAAY,EAAtC,EAAuB,CAAe,CAAC;QAC7C,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACxC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAY,EACZ,GAAY,EACZ,iBAAyD;IAEzD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,KACpD,KAAK,EADoD,WAAW,UACpE,KAAK,EADD,wDAAkE,CACjE,CAAC;IACR,MAAM,MAAM,GACV,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEnC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAS,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,CAAC,QAAQ,GAAG,QAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YACrC,CAAC;YAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;oBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YAC1C,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,oBAAoB,CAAC,UAAW,EAAE,GAAG,CAAC,CAAC;QAC5D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,UAAW,CAAC;QAC3E,MAAM,YAAY,GAAG,mBAAmB,CACtC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,CACT,CAAC;QACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,kBAAkB,CAC9B,YAAa,EACb,GAAG,CAAC,UAAU,EACd,iBAAiB,CAClB,CAAC;QACF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAClB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAGY;IAEZ,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAA4C;IAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,mEAAmE;IACnE,IACE,OAAO,KAAK,IAAI;QAChB,QAAQ,KAAK,IAAI;QACjB,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,QAAQ,KAAK,QAAQ,EAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CACpB,KAAY,EACZ,SAA6B;IAE7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,IAAI,cAAc,IAAI,SAAS,EAAE,CAAC;gBAChC,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CACrE,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,OAAO,CACL,KAAK,CAAC,OAAO,KAAK,IAAI;oBACrB,SAAqB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAC9C,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,OAAO,IAAA,6BAAe,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YAC7B,OAAO,IAAA,kCAAoB,EAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,IAAA,6BAAe,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,IAAA,6BAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAA,mCAAqB,EAAC,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,KAA4B,CAAC;AACtC,CAAC;AAED,kCAAkC;AAClC,MAAM,oBAAoB,GAAG;IAC3B,SAAS;IACT,UAAU;IACV,UAAU;IACV,QAAQ;IACR,eAAe;IACf,KAAK;CACN,CAAC;AAEF,SAAS,qBAAqB,CAAC,IAAc;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAElD,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAY,EACZ,IAAc,EACd,iBAAyD;IAEzD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,KACnD,KAAK,EADmD,WAAW,UACnE,KAAK,EADD,uDAAiE,CAChE,CAAC;IACR,MAAM,MAAM,GAA0B,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEvE,MAAM,aAAa,GACjB,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAS,CAAC,IAAI;QAC3C,CAAC,CAAC,QAAS,CAAC,IAAI;QAChB,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpC,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC;QAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC/B,CAAC;YAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;gBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QAC1C,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,oBAAoB,CAAC,UAAW,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,SAAU,CAAC;QACxE,MAAM,YAAY,GAAG,mBAAmB,CACtC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,CACR,CAAC;QACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,kBAAkB,CAC9B,YAAa,EACb,IAAI,CAAC,UAAU,EACf,iBAAiB,CAClB,CAAC;QACF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAuB;IAEvB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAqC,CAAC;IACvE,OAAO,CAAC,GAAY,EAAE,EAAE;QACtB,MAAM,KAAK,GAAU,EAAE,CAAC;QAExB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBACvC,iEAAiE;gBACjE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC;AAQD,SAAS,wBAAwB,CAC/B,aAA4B;IAE5B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC7D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiB,CAAC;IAClD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAqC,CAAC;IAEvE,OAAO,CAAC,IAAc,EAAE,EAAE;;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjD,yEAAyE;QACzE,mFAAmF;QACnF,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,iBAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACjE,CAAC;QAED,uCAAuC;QACvC,MAAM,oBAAoB,GAAG,MAAA,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;QAC1D,IAAI,YAAoB,CAAC;QACzB,IAAI,oBAAoB,KAAK,IAAI,EAAE,CAAC;YAClC,YAAY,GAAG,uBAAuB,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACzD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM;oBACJ,IAAA,uCAA0B,EAAC,oBAAoB,CAAC,CAAC,eAAe,CAAC;gBACnE,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,YAAY,GAAG,MAAM,CAAC;QACxB,CAAC;QAED,sEAAsE;QACtE,IAAI,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAqB;gBACtC,GAAG,aAAa,CAAC,gBAAgB;aAClC,CAAC;YACF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,UAAU,EAAE,CAAC;oBACf,aAAa,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YACjE,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;QAED,6EAA6E;QAC7E,MAAM,aAAa,GAAU,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC;QAChE,IAAI,WAAW,GAAG,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACtE,WAAW,GAAG,KAAK,CAAC;YACtB,CAAC;YACD,IAAI,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,2BAA2B;QAC3B,IAAI,WAAW,EAAE,CAAC;YAChB,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,iBAAiB,CAAC,aAAa,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAmB;IACxC,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE;QAClD,KAAK,EAAE,EAAE,KAAK,EAAE,yBAAiB,EAAE;KACpC;IACD,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;CACzB,CAAC;AAEF,SAAgB,sBAAsB,CACpC,UAA+C;IAE/C,MAAM,aAAa,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAEvD,gEAAgE;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAGlB,CAAC;IACJ,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;;QAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,MAAA,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC;YACxD,EAAE,GAAG,sBAAsB,CAAC;gBAC1B,iBAAiB;gBACjB,GAAG,aAAa,CAAC,kBAAkB;gBACnC,GAAG,KAAK;aACT,CAAC,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\nimport { color, type RgbColor, rgbToHex, validHex } from '@uiw/react-color';\n\nimport {\n clampNumericValue,\n compareNumericValues,\n getNumericWeight,\n isBigintLiteral,\n lerpColor,\n numericValuesEqual,\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n type RangeLiteral,\n resolveNumericLiteral,\n resolveRangeLiteral,\n} from '../_generated/style-rules';\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport {\n type Caption,\n type ColorRange,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type GraphStyleRule,\n type NonStaticStyles,\n type Style,\n type UniqueColors,\n type Value,\n type Where,\n} from './style-types';\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nexport const UNIQUE_COLORS_PALETTE = Object.values(tokens.graph).filter(\n validHex,\n);\n\ntype StyleMatchers = {\n globalLabelRules: GraphStyleRule[];\n globalReltypeRules: GraphStyleRule[];\n rulesByLabel: Map<string, GraphStyleRule[]>;\n rulesByType: Map<string, GraphStyleRule[]>;\n};\n\nfunction compareByPriorityAscending(\n a: GraphStyleRule,\n b: GraphStyleRule,\n): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: GraphStyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, GraphStyleRule[]>();\n const rulesByType = new Map<string, GraphStyleRule[]>();\n const globalLabelRules: GraphStyleRule[] = [];\n const globalReltypeRules: GraphStyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.isDisabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `GraphStyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: GraphStyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\n/**\n * Interpolates a color from a ColorRange based on a graph item's property value.\n * Returns a #rrggbb hex string, or null if the colorRange config is invalid\n * (bad hex colors, invalid value range, missing/non-numeric property).\n */\nfunction getInterpolatedColor(\n colorRange: ColorRange,\n graphItem: NodeData | RelData,\n): string | null {\n const {\n onProperty,\n minValue,\n minColor,\n maxValue,\n maxColor,\n midValue,\n midColor,\n } = colorRange;\n\n if (!validHex(minColor) || !validHex(maxColor)) {\n return null;\n }\n const minRgb = color(minColor).rgb;\n const maxRgb = color(maxColor).rgb;\n const resolvedMinValue = resolveRangeLiteral(minValue);\n const resolvedMaxValue = resolveRangeLiteral(maxValue);\n if (resolvedMinValue === null || resolvedMaxValue === null) {\n return null;\n }\n const boundsOrder = compareNumericValues(resolvedMinValue, resolvedMaxValue);\n if (boundsOrder === null) {\n return null;\n }\n const actualMinValue = boundsOrder <= 0 ? resolvedMinValue : resolvedMaxValue;\n const actualMaxValue = boundsOrder <= 0 ? resolvedMaxValue : resolvedMinValue;\n\n // Validate mid stop if provided\n let midRgb: RgbColor | undefined = undefined;\n const resolvedMidValue =\n midValue === undefined ? undefined : resolveRangeLiteral(midValue);\n if (resolvedMidValue === null) {\n return null;\n }\n if (midValue !== undefined && midColor !== undefined) {\n const minToMid = compareNumericValues(actualMinValue, resolvedMidValue!);\n const midToMax = compareNumericValues(resolvedMidValue!, actualMaxValue);\n const isMidInRange =\n minToMid !== null && midToMax !== null && minToMid <= 0 && midToMax <= 0;\n if (!isMidInRange || !validHex(midColor)) {\n return null;\n }\n midRgb = color(midColor).rgb;\n }\n\n const prop = graphItem.properties[onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number' && typeof rawValue !== 'bigint') {\n return null;\n }\n\n const clampedValue = clampNumericValue(\n rawValue,\n actualMinValue,\n actualMaxValue,\n );\n if (clampedValue === null) {\n return null;\n }\n\n let rgb: RgbColor;\n\n if (midRgb !== undefined && resolvedMidValue !== undefined) {\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMidValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n const isBetweenMinAndMid = weight <= 1;\n if (isBetweenMinAndMid) {\n rgb = lerpColor(minRgb, midRgb, weight);\n } else {\n const secondWeight = getNumericWeight(\n resolvedMidValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (secondWeight === null) {\n return null;\n }\n rgb = lerpColor(midRgb, maxRgb, secondWeight);\n }\n } else {\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n rgb = lerpColor(minRgb, maxRgb, weight);\n }\n\n return rgbToHex(rgb);\n}\n\n/**\n * Interpolates a numeric size/width from a range based on a graph item's property value.\n * Returns the interpolated number, or null if the property is missing or non-numeric.\n */\nfunction getInterpolatedSize(\n prop: PortableProperty | undefined,\n minValue: RangeLiteral,\n maxValue: RangeLiteral,\n minOut: number,\n maxOut: number,\n): number | null {\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number' && typeof rawValue !== 'bigint') {\n return null;\n }\n\n const resolvedMinValue = resolveRangeLiteral(minValue);\n const resolvedMaxValue = resolveRangeLiteral(maxValue);\n if (resolvedMinValue === null || resolvedMaxValue === null) {\n return null;\n }\n const clampedValue = clampNumericValue(\n rawValue,\n resolvedMinValue,\n resolvedMaxValue,\n );\n if (clampedValue === null) {\n return null;\n }\n const weight = getNumericWeight(\n resolvedMinValue,\n resolvedMaxValue,\n clampedValue,\n );\n if (weight === null) {\n return null;\n }\n return minOut * (1 - weight) + maxOut * weight;\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | bigint | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'Integer':\n case 'float':\n return Number(prop.stringified);\n case 'bigint':\n case 'BigInt': {\n try {\n const value = prop.stringified.startsWith('\"')\n ? (JSON.parse(prop.stringified) as string)\n : prop.stringified;\n return BigInt(value);\n } catch {\n return null;\n }\n }\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n // Neo4j temporal types — parse to a number for comparison with\n // { datetime } and { time } rule literals. An unparseable value resolves to\n // null (treated as missing) rather than leaking a raw string into numeric\n // comparisons, matching Cypher null semantics.\n //\n // DateTime / LocalDateTime → Unix milliseconds (epoch ms)\n // LocalDateTime has no timezone; treated as UTC, same as date-only strings.\n case 'DateTime':\n case 'LocalDateTime':\n case 'Date': {\n const s = JSON.parse(prop.stringified) as string;\n return parseDateString(s);\n }\n // Time (ZonedTime) / LocalTime → UTC-normalised ms since midnight\n // LocalTime has no offset; treated as UTC.\n case 'Time':\n case 'LocalTime': {\n const s = JSON.parse(prop.stringified) as string;\n return parseTimeString(s);\n }\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\ntype ResolvedCypherValue = string | number | bigint | boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n if (\n (typeof leftVal === 'number' || typeof leftVal === 'bigint') &&\n (typeof rightVal === 'number' || typeof rightVal === 'bigint')\n ) {\n return numericValuesEqual(leftVal, rightVal);\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\n/**\n * Returns whether a graph item is targeted by a single style rule.\n *\n * This evaluates both the rule's node label or relationship type selector and\n * its optional `where` clause. Disabled rules never match. Cypher-style\n * three-valued logic is reduced to a boolean: only `true` matches, while\n * `false` and `null` do not.\n *\n * Use {@link compileGraphStyleRules} to evaluate the final style produced by a\n * cascade of rules.\n */\nexport function doesGraphStyleRuleMatch(\n item: NodeData | RelData,\n rule: GraphStyleRule,\n): boolean {\n if (rule.isDisabled === true) {\n return false;\n }\n\n if ('label' in rule.match) {\n if (!('labelsSorted' in item)) {\n return false;\n }\n if (\n rule.match.label !== null &&\n !item.labelsSorted.includes(rule.match.label)\n ) {\n return false;\n }\n } else if ('reltype' in rule.match) {\n if (!('type' in item)) {\n return false;\n }\n if (rule.match.reltype !== null && item.type !== rule.match.reltype) {\n return false;\n }\n } else {\n return false;\n }\n\n return evaluateWhere(item, rule.where) === true;\n}\n\n/**\n * Resolves a color for the given property value, using the uniqueColors object\n * reference as the per-rule key in uniqueColorsCache. Assigns a new palette color\n * on first encounter (first-come, first-served). Returns null if the property is\n * missing or null.\n */\nfunction resolveUniqueColor(\n uniqueColors: UniqueColors,\n properties: Record<string, PortableProperty | undefined>,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): string | null {\n const prop = properties[uniqueColors.onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (rawValue === null) {\n return null;\n }\n const valueKey = String(rawValue);\n\n let valueMap = uniqueColorsCache.get(uniqueColors);\n if (valueMap === undefined) {\n valueMap = new Map();\n uniqueColorsCache.set(uniqueColors, valueMap);\n }\n\n let assignedColor = valueMap.get(valueKey);\n if (assignedColor === undefined) {\n assignedColor =\n UNIQUE_COLORS_PALETTE[valueMap.size % UNIQUE_COLORS_PALETTE.length]!;\n valueMap.set(valueKey, assignedColor);\n }\n\n return assignedColor;\n}\n\nfunction shouldUseProperty(\n prop: { isDisabled?: boolean } | undefined,\n): boolean {\n return prop !== undefined && prop.isDisabled !== true;\n}\n\nfunction evaluateStaticStyle({\n overlayIcon,\n ...scalarStyle\n}: Omit<Style, NonStaticStyles>) {\n const result: Record<string, unknown> = {};\n\n for (const [key, prop] of Object.entries(scalarStyle)) {\n if (shouldUseProperty(prop)) {\n result[key] = prop.value;\n }\n }\n\n if (shouldUseProperty(overlayIcon)) {\n const { ...overlayIconProps } = overlayIcon!;\n result.overlayIcon = overlayIconProps;\n }\n\n return result;\n}\n\nfunction evaluateRelStyle(\n style: Style,\n rel: RelData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlRelationshipStyle {\n const { captions, colorRange, widthRange, uniqueColors, ...staticStyle } =\n style;\n const result: EvaluatedNvlRelationshipStyle =\n evaluateStaticStyle(staticStyle);\n\n if (shouldUseProperty(captions) && captions!.text) {\n result.captions = captions!.text.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n });\n\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, rel);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(widthRange)) {\n const { onProperty, minValue, maxValue, minWidth, maxWidth } = widthRange!;\n const interpolated = getInterpolatedSize(\n rel.properties[onProperty],\n minValue,\n maxValue,\n minWidth,\n maxWidth,\n );\n if (interpolated !== null) {\n result.width = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n rel.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<ResolvedCypherValue>,\n b: NonNullable<ResolvedCypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): ResolvedCypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n if ('datetime' in value) {\n return parseDateString(value.datetime);\n }\n if ('localdatetime' in value) {\n return parseLocalDateString(value.localdatetime);\n }\n if ('time' in value) {\n return parseTimeString(value.time);\n }\n if (isBigintLiteral(value)) {\n return resolveNumericLiteral(value);\n }\n }\n\n return value as ResolvedCypherValue;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n style: Style,\n node: NodeData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlNodeStyle {\n const { captions, colorRange, sizeRange, uniqueColors, ...staticStyle } =\n style;\n const result: EvaluatedNvlNodeStyle = evaluateStaticStyle(staticStyle);\n\n const captionSource =\n shouldUseProperty(captions) && captions!.text\n ? captions!.text\n : [getDefaultNodeCaption(node)];\n\n result.captions = captionSource.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n });\n\n if (shouldUseProperty(captions)) {\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, node);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(sizeRange)) {\n const { onProperty, minValue, maxValue, minSize, maxSize } = sizeRange!;\n const interpolated = getInterpolatedSize(\n node.properties[onProperty],\n minValue,\n maxValue,\n minSize,\n maxSize,\n );\n if (interpolated !== null) {\n result.size = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n node.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\nfunction createRelStyleFunction(\n rules: GraphStyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n return (rel: RelData) => {\n const style: Style = {};\n\n for (const rule of rules) {\n if (doesGraphStyleRuleMatch(rel, rule)) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n\n return evaluateRelStyle(style, rel, uniqueColorsCache);\n };\n}\n\nexport type CompiledGraphStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, GraphStyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free and none use\n // uniqueColors, the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node, uniqueColorsCache);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: GraphStyleRule[] = [\n ...styleMatchers.globalLabelRules,\n ];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free and uniqueColors-free.\n const collectStyles: Style = { color: { value: defaultColor } };\n let isCacheable = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined || rule.apply.uniqueColors !== undefined) {\n isCacheable = false;\n }\n if (doesGraphStyleRuleMatch(node, rule)) {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free and uniqueColors-free, the merged style\n // depends only on labels. Cache it so subsequent nodes with the same label\n // set skip rule iteration.\n if (isCacheable) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node, uniqueColorsCache);\n };\n}\n\nconst DEFAULT_REL_STYLE: GraphStyleRule = {\n apply: {\n captions: { text: [{ value: { useType: true } }] },\n color: { value: DEFAULT_REL_COLOR },\n },\n match: { reltype: null },\n};\n\nexport function compileGraphStyleRules(\n styleRules: GraphStyleRule[] | null | undefined,\n): CompiledGraphStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}