@tenphi/tasty 2.0.3 → 2.1.0

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 (323) hide show
  1. package/dist/{ssr/async-storage.js → async-storage-B7_o6FKt.js} +2 -2
  2. package/dist/async-storage-B7_o6FKt.js.map +1 -0
  3. package/dist/{ssr/collector.js → collector-DrgDE7QB.js} +5 -10
  4. package/dist/collector-DrgDE7QB.js.map +1 -0
  5. package/dist/{ssr/collector.d.ts → collector-LuU1vZ68.d.ts} +3 -3
  6. package/dist/config-_aQ_PZ-P.js +10131 -0
  7. package/dist/config-_aQ_PZ-P.js.map +1 -0
  8. package/dist/config-vuCRkBWX.d.ts +884 -0
  9. package/dist/{ssr/context.js → context-CkSg-kDT.js} +11 -3
  10. package/dist/context-CkSg-kDT.js.map +1 -0
  11. package/dist/core/index.d.ts +5 -34
  12. package/dist/core/index.js +6 -27
  13. package/dist/core-BqO8pplb.js +1592 -0
  14. package/dist/core-BqO8pplb.js.map +1 -0
  15. package/dist/{zero/extractor.js → css-writer-D--REwtp.js} +74 -11
  16. package/dist/css-writer-D--REwtp.js.map +1 -0
  17. package/dist/{ssr/format-global-rules.js → format-global-rules-Dbc_1tc3.js} +2 -2
  18. package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
  19. package/dist/format-rules-xwteB7a1.js +143 -0
  20. package/dist/format-rules-xwteB7a1.js.map +1 -0
  21. package/dist/{ssr/hydrate.js → hydrate-BvPT4ndL.js} +3 -3
  22. package/dist/hydrate-BvPT4ndL.js.map +1 -0
  23. package/dist/index-ZRxZWzlj.d.ts +1602 -0
  24. package/dist/{styles/types.d.ts → index-dUtwpOux.d.ts} +707 -5
  25. package/dist/index.d.ts +5 -51
  26. package/dist/index.js +732 -36
  27. package/dist/index.js.map +1 -0
  28. package/dist/keyframes-ClPFWy33.js +587 -0
  29. package/dist/keyframes-ClPFWy33.js.map +1 -0
  30. package/dist/{utils/merge-styles.js → merge-styles-BUQsEpbv.js} +3 -4
  31. package/dist/merge-styles-BUQsEpbv.js.map +1 -0
  32. package/dist/{utils/merge-styles.d.ts → merge-styles-CtDJMhpJ.d.ts} +3 -3
  33. package/dist/{utils/resolve-recipes.js → resolve-recipes-C0-AMzCz.js} +4 -6
  34. package/dist/resolve-recipes-C0-AMzCz.js.map +1 -0
  35. package/dist/ssr/astro-client.js +1 -1
  36. package/dist/ssr/astro.js +4 -4
  37. package/dist/ssr/index.d.ts +44 -4
  38. package/dist/ssr/index.js +4 -4
  39. package/dist/ssr/next.d.ts +1 -1
  40. package/dist/ssr/next.js +6 -6
  41. package/dist/ssr/next.js.map +1 -1
  42. package/dist/static/index.d.ts +91 -5
  43. package/dist/static/index.js +49 -3
  44. package/dist/static/index.js.map +1 -0
  45. package/dist/zero/babel.d.ts +1 -1
  46. package/dist/zero/babel.js +10 -6
  47. package/dist/zero/babel.js.map +1 -1
  48. package/dist/zero/index.d.ts +67 -3
  49. package/dist/zero/index.js +1 -2
  50. package/docs/injector.md +2 -2
  51. package/package.json +10 -9
  52. package/dist/_virtual/_rolldown/runtime.js +0 -7
  53. package/dist/chunks/cacheKey.d.ts +0 -1
  54. package/dist/chunks/cacheKey.js +0 -77
  55. package/dist/chunks/cacheKey.js.map +0 -1
  56. package/dist/chunks/definitions.d.ts +0 -37
  57. package/dist/chunks/definitions.js +0 -258
  58. package/dist/chunks/definitions.js.map +0 -1
  59. package/dist/chunks/index.d.ts +0 -1
  60. package/dist/chunks/renderChunk.d.ts +0 -1
  61. package/dist/chunks/renderChunk.js +0 -59
  62. package/dist/chunks/renderChunk.js.map +0 -1
  63. package/dist/compute-styles.d.ts +0 -31
  64. package/dist/compute-styles.js +0 -322
  65. package/dist/compute-styles.js.map +0 -1
  66. package/dist/config.d.ts +0 -407
  67. package/dist/config.js +0 -591
  68. package/dist/config.js.map +0 -1
  69. package/dist/counter-style/index.js +0 -51
  70. package/dist/counter-style/index.js.map +0 -1
  71. package/dist/debug.d.ts +0 -89
  72. package/dist/debug.js +0 -453
  73. package/dist/debug.js.map +0 -1
  74. package/dist/font-face/index.js +0 -63
  75. package/dist/font-face/index.js.map +0 -1
  76. package/dist/hooks/index.d.ts +0 -7
  77. package/dist/hooks/useCounterStyle.d.ts +0 -36
  78. package/dist/hooks/useCounterStyle.js +0 -65
  79. package/dist/hooks/useCounterStyle.js.map +0 -1
  80. package/dist/hooks/useFontFace.d.ts +0 -45
  81. package/dist/hooks/useFontFace.js +0 -66
  82. package/dist/hooks/useFontFace.js.map +0 -1
  83. package/dist/hooks/useGlobalStyles.d.ts +0 -46
  84. package/dist/hooks/useGlobalStyles.js +0 -88
  85. package/dist/hooks/useGlobalStyles.js.map +0 -1
  86. package/dist/hooks/useKeyframes.d.ts +0 -58
  87. package/dist/hooks/useKeyframes.js +0 -55
  88. package/dist/hooks/useKeyframes.js.map +0 -1
  89. package/dist/hooks/useProperty.d.ts +0 -81
  90. package/dist/hooks/useProperty.js +0 -96
  91. package/dist/hooks/useProperty.js.map +0 -1
  92. package/dist/hooks/useRawCSS.d.ts +0 -22
  93. package/dist/hooks/useRawCSS.js +0 -103
  94. package/dist/hooks/useRawCSS.js.map +0 -1
  95. package/dist/hooks/useStyles.d.ts +0 -40
  96. package/dist/hooks/useStyles.js +0 -31
  97. package/dist/hooks/useStyles.js.map +0 -1
  98. package/dist/injector/index.d.ts +0 -182
  99. package/dist/injector/index.js +0 -185
  100. package/dist/injector/index.js.map +0 -1
  101. package/dist/injector/injector.d.ts +0 -198
  102. package/dist/injector/injector.js +0 -651
  103. package/dist/injector/injector.js.map +0 -1
  104. package/dist/injector/sheet-manager.d.ts +0 -132
  105. package/dist/injector/sheet-manager.js +0 -699
  106. package/dist/injector/sheet-manager.js.map +0 -1
  107. package/dist/injector/types.d.ts +0 -235
  108. package/dist/keyframes/index.js +0 -206
  109. package/dist/keyframes/index.js.map +0 -1
  110. package/dist/parser/classify.js +0 -319
  111. package/dist/parser/classify.js.map +0 -1
  112. package/dist/parser/const.js +0 -60
  113. package/dist/parser/const.js.map +0 -1
  114. package/dist/parser/lru.js +0 -109
  115. package/dist/parser/lru.js.map +0 -1
  116. package/dist/parser/parser.d.ts +0 -25
  117. package/dist/parser/parser.js +0 -115
  118. package/dist/parser/parser.js.map +0 -1
  119. package/dist/parser/tokenizer.js +0 -69
  120. package/dist/parser/tokenizer.js.map +0 -1
  121. package/dist/parser/types.d.ts +0 -51
  122. package/dist/parser/types.js +0 -46
  123. package/dist/parser/types.js.map +0 -1
  124. package/dist/pipeline/conditions.d.ts +0 -134
  125. package/dist/pipeline/conditions.js +0 -406
  126. package/dist/pipeline/conditions.js.map +0 -1
  127. package/dist/pipeline/exclusive.js +0 -389
  128. package/dist/pipeline/exclusive.js.map +0 -1
  129. package/dist/pipeline/index.d.ts +0 -55
  130. package/dist/pipeline/index.js +0 -749
  131. package/dist/pipeline/index.js.map +0 -1
  132. package/dist/pipeline/materialize-contradictions.js +0 -125
  133. package/dist/pipeline/materialize-contradictions.js.map +0 -1
  134. package/dist/pipeline/materialize.js +0 -1038
  135. package/dist/pipeline/materialize.js.map +0 -1
  136. package/dist/pipeline/parseStateKey.d.ts +0 -15
  137. package/dist/pipeline/parseStateKey.js +0 -446
  138. package/dist/pipeline/parseStateKey.js.map +0 -1
  139. package/dist/pipeline/simplify.js +0 -725
  140. package/dist/pipeline/simplify.js.map +0 -1
  141. package/dist/pipeline/warnings.js +0 -18
  142. package/dist/pipeline/warnings.js.map +0 -1
  143. package/dist/plugins/index.d.ts +0 -2
  144. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  145. package/dist/plugins/okhsl-plugin.js +0 -97
  146. package/dist/plugins/okhsl-plugin.js.map +0 -1
  147. package/dist/plugins/types.d.ts +0 -87
  148. package/dist/properties/index.js +0 -222
  149. package/dist/properties/index.js.map +0 -1
  150. package/dist/properties/property-type-resolver.d.ts +0 -24
  151. package/dist/properties/property-type-resolver.js +0 -90
  152. package/dist/properties/property-type-resolver.js.map +0 -1
  153. package/dist/rsc-cache.js +0 -79
  154. package/dist/rsc-cache.js.map +0 -1
  155. package/dist/ssr/async-storage.d.ts +0 -17
  156. package/dist/ssr/async-storage.js.map +0 -1
  157. package/dist/ssr/collect-auto-properties.js +0 -58
  158. package/dist/ssr/collect-auto-properties.js.map +0 -1
  159. package/dist/ssr/collector.js.map +0 -1
  160. package/dist/ssr/context.js.map +0 -1
  161. package/dist/ssr/format-global-rules.js.map +0 -1
  162. package/dist/ssr/format-keyframes.js +0 -69
  163. package/dist/ssr/format-keyframes.js.map +0 -1
  164. package/dist/ssr/format-property.js +0 -49
  165. package/dist/ssr/format-property.js.map +0 -1
  166. package/dist/ssr/format-rules.js +0 -73
  167. package/dist/ssr/format-rules.js.map +0 -1
  168. package/dist/ssr/hydrate.d.ts +0 -29
  169. package/dist/ssr/hydrate.js.map +0 -1
  170. package/dist/ssr/ssr-collector-ref.js +0 -29
  171. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  172. package/dist/states/index.d.ts +0 -49
  173. package/dist/states/index.js +0 -170
  174. package/dist/states/index.js.map +0 -1
  175. package/dist/static/tastyStatic.d.ts +0 -46
  176. package/dist/static/tastyStatic.js +0 -30
  177. package/dist/static/tastyStatic.js.map +0 -1
  178. package/dist/static/types.d.ts +0 -49
  179. package/dist/static/types.js +0 -24
  180. package/dist/static/types.js.map +0 -1
  181. package/dist/styles/border.d.ts +0 -25
  182. package/dist/styles/border.js +0 -120
  183. package/dist/styles/border.js.map +0 -1
  184. package/dist/styles/color.d.ts +0 -14
  185. package/dist/styles/color.js +0 -26
  186. package/dist/styles/color.js.map +0 -1
  187. package/dist/styles/const.js +0 -17
  188. package/dist/styles/const.js.map +0 -1
  189. package/dist/styles/createStyle.js +0 -79
  190. package/dist/styles/createStyle.js.map +0 -1
  191. package/dist/styles/dimension.js +0 -109
  192. package/dist/styles/dimension.js.map +0 -1
  193. package/dist/styles/directional.js +0 -133
  194. package/dist/styles/directional.js.map +0 -1
  195. package/dist/styles/display.d.ts +0 -30
  196. package/dist/styles/display.js +0 -73
  197. package/dist/styles/display.js.map +0 -1
  198. package/dist/styles/fade.d.ts +0 -15
  199. package/dist/styles/fade.js +0 -62
  200. package/dist/styles/fade.js.map +0 -1
  201. package/dist/styles/fill.d.ts +0 -42
  202. package/dist/styles/fill.js +0 -51
  203. package/dist/styles/fill.js.map +0 -1
  204. package/dist/styles/flow.d.ts +0 -16
  205. package/dist/styles/flow.js +0 -12
  206. package/dist/styles/flow.js.map +0 -1
  207. package/dist/styles/gap.d.ts +0 -31
  208. package/dist/styles/gap.js +0 -38
  209. package/dist/styles/gap.js.map +0 -1
  210. package/dist/styles/height.d.ts +0 -17
  211. package/dist/styles/height.js +0 -19
  212. package/dist/styles/height.js.map +0 -1
  213. package/dist/styles/index.d.ts +0 -1
  214. package/dist/styles/index.js +0 -8
  215. package/dist/styles/index.js.map +0 -1
  216. package/dist/styles/inset.d.ts +0 -24
  217. package/dist/styles/inset.js +0 -34
  218. package/dist/styles/inset.js.map +0 -1
  219. package/dist/styles/list.d.ts +0 -16
  220. package/dist/styles/list.js +0 -100
  221. package/dist/styles/list.js.map +0 -1
  222. package/dist/styles/margin.d.ts +0 -24
  223. package/dist/styles/margin.js +0 -32
  224. package/dist/styles/margin.js.map +0 -1
  225. package/dist/styles/outline.d.ts +0 -29
  226. package/dist/styles/outline.js +0 -55
  227. package/dist/styles/outline.js.map +0 -1
  228. package/dist/styles/padding.d.ts +0 -24
  229. package/dist/styles/padding.js +0 -32
  230. package/dist/styles/padding.js.map +0 -1
  231. package/dist/styles/placement.d.ts +0 -37
  232. package/dist/styles/placement.js +0 -74
  233. package/dist/styles/placement.js.map +0 -1
  234. package/dist/styles/predefined.d.ts +0 -71
  235. package/dist/styles/predefined.js +0 -237
  236. package/dist/styles/predefined.js.map +0 -1
  237. package/dist/styles/preset.d.ts +0 -52
  238. package/dist/styles/preset.js +0 -127
  239. package/dist/styles/preset.js.map +0 -1
  240. package/dist/styles/radius.d.ts +0 -12
  241. package/dist/styles/radius.js +0 -83
  242. package/dist/styles/radius.js.map +0 -1
  243. package/dist/styles/scrollMargin.d.ts +0 -24
  244. package/dist/styles/scrollMargin.js +0 -32
  245. package/dist/styles/scrollMargin.js.map +0 -1
  246. package/dist/styles/scrollbar.d.ts +0 -25
  247. package/dist/styles/scrollbar.js +0 -51
  248. package/dist/styles/scrollbar.js.map +0 -1
  249. package/dist/styles/shadow.d.ts +0 -14
  250. package/dist/styles/shadow.js +0 -25
  251. package/dist/styles/shadow.js.map +0 -1
  252. package/dist/styles/shared.js +0 -17
  253. package/dist/styles/shared.js.map +0 -1
  254. package/dist/styles/transition.d.ts +0 -14
  255. package/dist/styles/transition.js +0 -159
  256. package/dist/styles/transition.js.map +0 -1
  257. package/dist/styles/width.d.ts +0 -17
  258. package/dist/styles/width.js +0 -19
  259. package/dist/styles/width.js.map +0 -1
  260. package/dist/tasty.d.ts +0 -134
  261. package/dist/tasty.js +0 -248
  262. package/dist/tasty.js.map +0 -1
  263. package/dist/types.d.ts +0 -184
  264. package/dist/utils/cache-wrapper.js +0 -21
  265. package/dist/utils/cache-wrapper.js.map +0 -1
  266. package/dist/utils/case-converter.js +0 -8
  267. package/dist/utils/case-converter.js.map +0 -1
  268. package/dist/utils/color-math.d.ts +0 -46
  269. package/dist/utils/color-math.js +0 -749
  270. package/dist/utils/color-math.js.map +0 -1
  271. package/dist/utils/color-space.d.ts +0 -5
  272. package/dist/utils/color-space.js +0 -228
  273. package/dist/utils/color-space.js.map +0 -1
  274. package/dist/utils/colors.d.ts +0 -5
  275. package/dist/utils/colors.js +0 -10
  276. package/dist/utils/colors.js.map +0 -1
  277. package/dist/utils/css-types.d.ts +0 -7
  278. package/dist/utils/deps-equal.js +0 -15
  279. package/dist/utils/deps-equal.js.map +0 -1
  280. package/dist/utils/dotize.d.ts +0 -26
  281. package/dist/utils/dotize.js +0 -122
  282. package/dist/utils/dotize.js.map +0 -1
  283. package/dist/utils/filter-base-props.d.ts +0 -15
  284. package/dist/utils/filter-base-props.js +0 -45
  285. package/dist/utils/filter-base-props.js.map +0 -1
  286. package/dist/utils/get-display-name.d.ts +0 -7
  287. package/dist/utils/get-display-name.js +0 -10
  288. package/dist/utils/get-display-name.js.map +0 -1
  289. package/dist/utils/has-keys.js +0 -13
  290. package/dist/utils/has-keys.js.map +0 -1
  291. package/dist/utils/hash.js +0 -14
  292. package/dist/utils/hash.js.map +0 -1
  293. package/dist/utils/is-dev-env.js +0 -19
  294. package/dist/utils/is-dev-env.js.map +0 -1
  295. package/dist/utils/is-valid-element-type.js +0 -15
  296. package/dist/utils/is-valid-element-type.js.map +0 -1
  297. package/dist/utils/merge-styles.js.map +0 -1
  298. package/dist/utils/mod-attrs.d.ts +0 -6
  299. package/dist/utils/mod-attrs.js +0 -20
  300. package/dist/utils/mod-attrs.js.map +0 -1
  301. package/dist/utils/process-tokens.d.ts +0 -17
  302. package/dist/utils/process-tokens.js +0 -83
  303. package/dist/utils/process-tokens.js.map +0 -1
  304. package/dist/utils/resolve-recipes.d.ts +0 -17
  305. package/dist/utils/resolve-recipes.js.map +0 -1
  306. package/dist/utils/selector-transform.js +0 -32
  307. package/dist/utils/selector-transform.js.map +0 -1
  308. package/dist/utils/string.js +0 -8
  309. package/dist/utils/string.js.map +0 -1
  310. package/dist/utils/styles.d.ts +0 -99
  311. package/dist/utils/styles.js +0 -220
  312. package/dist/utils/styles.js.map +0 -1
  313. package/dist/utils/typography.d.ts +0 -58
  314. package/dist/utils/typography.js +0 -51
  315. package/dist/utils/typography.js.map +0 -1
  316. package/dist/utils/warnings.d.ts +0 -16
  317. package/dist/utils/warnings.js +0 -16
  318. package/dist/utils/warnings.js.map +0 -1
  319. package/dist/zero/css-writer.d.ts +0 -45
  320. package/dist/zero/css-writer.js +0 -73
  321. package/dist/zero/css-writer.js.map +0 -1
  322. package/dist/zero/extractor.d.ts +0 -24
  323. package/dist/zero/extractor.js.map +0 -1
@@ -1,725 +0,0 @@
1
- import { Lru } from "../parser/lru.js";
2
- import { and, createOwnCondition, createParentCondition, createRootCondition, falseCondition, getConditionUniqueId, not, or, trueCondition } from "./conditions.js";
3
- //#region src/pipeline/simplify.ts
4
- /**
5
- * Condition Simplification Engine
6
- *
7
- * Simplifies condition trees by applying boolean algebra rules,
8
- * detecting contradictions, merging ranges, and deduplicating terms.
9
- *
10
- * This is critical for:
11
- * 1. Detecting invalid combinations (A & !A → FALSE)
12
- * 2. Reducing CSS output size
13
- * 3. Producing cleaner selectors
14
- */
15
- const simplifyCache = new Lru(5e3);
16
- /**
17
- * Simplify a condition tree aggressively.
18
- *
19
- * This applies all possible simplification rules:
20
- * - Boolean algebra (identity, annihilator, idempotent, absorption)
21
- * - Contradiction detection (A & !A → FALSE)
22
- * - Tautology detection (A | !A → TRUE)
23
- * - Range intersection for numeric queries
24
- * - Attribute value conflict detection
25
- * - Deduplication and sorting
26
- */
27
- function simplifyCondition(node) {
28
- const key = getConditionUniqueId(node);
29
- const cached = simplifyCache.get(key);
30
- if (cached) return cached;
31
- const result = simplifyInner(node);
32
- simplifyCache.set(key, result);
33
- return result;
34
- }
35
- function simplifyInner(node) {
36
- if (node.kind === "true" || node.kind === "false") return node;
37
- if (node.kind === "state") {
38
- if ((node.type === "root" || node.type === "own" || node.type === "parent") && !node.negated) {
39
- const simplifiedInner = simplifyInner(node.innerCondition);
40
- if (simplifiedInner.kind === "false") return falseCondition();
41
- if (simplifiedInner === node.innerCondition) return node;
42
- if (node.type === "root") return createRootCondition(simplifiedInner, false, node.raw);
43
- if (node.type === "own") return createOwnCondition(simplifiedInner, false, node.raw);
44
- return createParentCondition(simplifiedInner, node.direct, false, node.raw);
45
- }
46
- return node;
47
- }
48
- if (node.kind === "compound") {
49
- const simplifiedChildren = node.children.map((c) => simplifyInner(c));
50
- if (node.operator === "AND") return simplifyAnd(simplifiedChildren);
51
- else return simplifyOr(simplifiedChildren);
52
- }
53
- return node;
54
- }
55
- function simplifyAnd(children) {
56
- let terms = [];
57
- for (const child of children) {
58
- if (child.kind === "false") return falseCondition();
59
- if (child.kind === "true") continue;
60
- if (child.kind === "compound" && child.operator === "AND") terms.push(...child.children);
61
- else terms.push(child);
62
- }
63
- if (terms.length === 0) return trueCondition();
64
- if (terms.length === 1) return terms[0];
65
- if (hasContradiction(terms)) return falseCondition();
66
- if (hasRangeContradiction(terms)) return falseCondition();
67
- if (hasAttributeConflict(terms)) return falseCondition();
68
- if (hasContainerStyleConflict(terms)) return falseCondition();
69
- terms = removeImpliedNegations(terms);
70
- terms = deduplicateTerms(terms);
71
- terms = mergeRanges(terms);
72
- terms = sortTerms(terms);
73
- terms = applyAbsorptionAnd(terms);
74
- terms = applyConsensusAnd(terms);
75
- if (terms.length === 0) return trueCondition();
76
- if (terms.length === 1) return terms[0];
77
- return {
78
- kind: "compound",
79
- operator: "AND",
80
- children: terms
81
- };
82
- }
83
- function simplifyOr(children) {
84
- let terms = [];
85
- for (const child of children) {
86
- if (child.kind === "true") return trueCondition();
87
- if (child.kind === "false") continue;
88
- if (child.kind === "compound" && child.operator === "OR") terms.push(...child.children);
89
- else terms.push(child);
90
- }
91
- if (terms.length === 0) return falseCondition();
92
- if (terms.length === 1) return terms[0];
93
- if (hasTautology(terms)) return trueCondition();
94
- terms = deduplicateTerms(terms);
95
- terms = sortTerms(terms);
96
- terms = applyAbsorptionOr(terms);
97
- terms = applyComplementaryFactoring(terms);
98
- if (terms.length === 0) return falseCondition();
99
- if (terms.length === 1) return terms[0];
100
- return {
101
- kind: "compound",
102
- operator: "OR",
103
- children: terms
104
- };
105
- }
106
- /**
107
- * Check if any pair of terms has complementary negation (A and !A).
108
- * Used for both contradiction detection (in AND) and tautology detection (in OR),
109
- * since the underlying check is identical: the context determines the semantics.
110
- */
111
- function hasComplementaryPair(terms) {
112
- const uniqueIds = /* @__PURE__ */ new Set();
113
- for (const term of terms) {
114
- if (term.kind !== "state") continue;
115
- const id = term.uniqueId;
116
- const negatedId = term.negated ? id.slice(1) : `!${id}`;
117
- if (uniqueIds.has(negatedId)) return true;
118
- uniqueIds.add(id);
119
- }
120
- return false;
121
- }
122
- const hasContradiction = hasComplementaryPair;
123
- const hasTautology = hasComplementaryPair;
124
- /**
125
- * Check for range contradictions in media/container queries
126
- * e.g., @media(w < 400px) & @media(w > 800px) → FALSE
127
- *
128
- * Also handles negated conditions:
129
- * - Single-bound negations are inverted (not (w < 600px) → w >= 600px)
130
- * - Range negations create excluded ranges that are checked against positive bounds
131
- */
132
- function hasRangeContradiction(terms) {
133
- const mediaByDim = /* @__PURE__ */ new Map();
134
- const containerByDim = /* @__PURE__ */ new Map();
135
- for (const term of terms) {
136
- if (term.kind !== "state") continue;
137
- if (term.type === "media" && term.subtype === "dimension") {
138
- const key = term.dimension || "width";
139
- if (!mediaByDim.has(key)) mediaByDim.set(key, {
140
- positive: [],
141
- negated: []
142
- });
143
- const group = mediaByDim.get(key);
144
- if (term.negated) group.negated.push(term);
145
- else group.positive.push(term);
146
- }
147
- if (term.type === "container" && term.subtype === "dimension") {
148
- const key = `${term.containerName || "_"}:${term.dimension || "width"}`;
149
- if (!containerByDim.has(key)) containerByDim.set(key, {
150
- positive: [],
151
- negated: []
152
- });
153
- const group = containerByDim.get(key);
154
- if (term.negated) group.negated.push(term);
155
- else group.positive.push(term);
156
- }
157
- }
158
- for (const group of mediaByDim.values()) if (rangesAreImpossibleWithNegations(group.positive, group.negated)) return true;
159
- for (const group of containerByDim.values()) if (rangesAreImpossibleWithNegations(group.positive, group.negated)) return true;
160
- return false;
161
- }
162
- /**
163
- * Check if conditions are impossible, including negated conditions.
164
- *
165
- * For negated single-bound conditions:
166
- * not (w < 600px) → w >= 600px (inverted to lower bound)
167
- * not (w >= 800px) → w < 800px (inverted to upper bound)
168
- *
169
- * For negated range conditions:
170
- * not (400px <= w < 800px) → excludes [400, 800)
171
- * If the effective bounds fall entirely within an excluded range, it's impossible.
172
- */
173
- function rangesAreImpossibleWithNegations(positive, negated) {
174
- const bounds = computeEffectiveBounds(positive);
175
- const excludedRanges = [];
176
- for (const cond of negated) {
177
- const hasLower = cond.lowerBound?.valueNumeric != null;
178
- const hasUpper = cond.upperBound?.valueNumeric != null;
179
- if (hasLower && hasUpper) excludedRanges.push({
180
- lower: cond.lowerBound.valueNumeric,
181
- lowerInclusive: cond.lowerBound.inclusive,
182
- upper: cond.upperBound.valueNumeric,
183
- upperInclusive: cond.upperBound.inclusive
184
- });
185
- else if (hasUpper) {
186
- const value = cond.upperBound.valueNumeric;
187
- const inclusive = !cond.upperBound.inclusive;
188
- if (bounds.lowerBound === null || value > bounds.lowerBound) {
189
- bounds.lowerBound = value;
190
- bounds.lowerInclusive = inclusive;
191
- } else if (value === bounds.lowerBound && !inclusive) bounds.lowerInclusive = false;
192
- } else if (hasLower) {
193
- const value = cond.lowerBound.valueNumeric;
194
- const inclusive = !cond.lowerBound.inclusive;
195
- if (bounds.upperBound === null || value < bounds.upperBound) {
196
- bounds.upperBound = value;
197
- bounds.upperInclusive = inclusive;
198
- } else if (value === bounds.upperBound && !inclusive) bounds.upperInclusive = false;
199
- }
200
- }
201
- if (bounds.lowerBound !== null && bounds.upperBound !== null) {
202
- if (bounds.lowerBound > bounds.upperBound) return true;
203
- if (bounds.lowerBound === bounds.upperBound && (!bounds.lowerInclusive || !bounds.upperInclusive)) return true;
204
- }
205
- if (bounds.lowerBound !== null && bounds.upperBound !== null && excludedRanges.length > 0) {
206
- for (const excluded of excludedRanges) if (boundsWithinExcludedRange(bounds, excluded)) return true;
207
- }
208
- return false;
209
- }
210
- /**
211
- * Compute effective bounds from positive (non-negated) conditions
212
- */
213
- function computeEffectiveBounds(conditions) {
214
- let lowerBound = null;
215
- let lowerInclusive = false;
216
- let upperBound = null;
217
- let upperInclusive = false;
218
- for (const cond of conditions) {
219
- if (cond.lowerBound?.valueNumeric != null) {
220
- const value = cond.lowerBound.valueNumeric;
221
- const inclusive = cond.lowerBound.inclusive;
222
- if (lowerBound === null || value > lowerBound) {
223
- lowerBound = value;
224
- lowerInclusive = inclusive;
225
- } else if (value === lowerBound && !inclusive) lowerInclusive = false;
226
- }
227
- if (cond.upperBound?.valueNumeric != null) {
228
- const value = cond.upperBound.valueNumeric;
229
- const inclusive = cond.upperBound.inclusive;
230
- if (upperBound === null || value < upperBound) {
231
- upperBound = value;
232
- upperInclusive = inclusive;
233
- } else if (value === upperBound && !inclusive) upperInclusive = false;
234
- }
235
- }
236
- return {
237
- lowerBound,
238
- lowerInclusive,
239
- upperBound,
240
- upperInclusive
241
- };
242
- }
243
- /**
244
- * Check if effective bounds fall entirely within an excluded range.
245
- *
246
- * For example:
247
- * Effective: [400, 800)
248
- * Excluded: [400, 800)
249
- * → bounds fall entirely within excluded range → impossible
250
- */
251
- function boundsWithinExcludedRange(bounds, excluded) {
252
- if (bounds.lowerBound === null || bounds.upperBound === null) return false;
253
- let lowerOk = false;
254
- if (bounds.lowerBound > excluded.lower) lowerOk = true;
255
- else if (bounds.lowerBound === excluded.lower) lowerOk = excluded.lowerInclusive || !bounds.lowerInclusive;
256
- let upperOk = false;
257
- if (bounds.upperBound < excluded.upper) upperOk = true;
258
- else if (bounds.upperBound === excluded.upper) upperOk = excluded.upperInclusive || !bounds.upperInclusive;
259
- return lowerOk && upperOk;
260
- }
261
- /**
262
- * Check for attribute value conflicts
263
- * e.g., [data-theme="dark"] & [data-theme="light"] → FALSE
264
- * e.g., [data-theme="dark"] & ![data-theme] → FALSE
265
- */
266
- /**
267
- * Generic value-conflict checker for grouped conditions.
268
- *
269
- * Groups terms by a key, splits into positive/negated, then checks:
270
- * 1. Multiple distinct positive values → conflict
271
- * 2. Positive value + negated existence (value === undefined) → conflict
272
- * 3. Positive value + negated same value → conflict
273
- */
274
- function hasGroupedValueConflict(terms, match, groupKey, getValue) {
275
- const groups = /* @__PURE__ */ new Map();
276
- for (const term of terms) {
277
- const matched = match(term);
278
- if (!matched) continue;
279
- const key = groupKey(matched);
280
- let group = groups.get(key);
281
- if (!group) {
282
- group = {
283
- positive: [],
284
- negated: []
285
- };
286
- groups.set(key, group);
287
- }
288
- if (matched.negated) group.negated.push(matched);
289
- else group.positive.push(matched);
290
- }
291
- for (const [, group] of groups) {
292
- const positiveValues = group.positive.map(getValue).filter((v) => v !== void 0);
293
- if (new Set(positiveValues).size > 1) return true;
294
- const hasPositiveValue = positiveValues.length > 0;
295
- const hasNegatedExistence = group.negated.some((t) => getValue(t) === void 0);
296
- if (hasPositiveValue && hasNegatedExistence) return true;
297
- for (const pos of group.positive) {
298
- const posVal = getValue(pos);
299
- if (posVal !== void 0) {
300
- for (const neg of group.negated) if (getValue(neg) === posVal) return true;
301
- }
302
- }
303
- }
304
- return false;
305
- }
306
- function hasAttributeConflict(terms) {
307
- if (hasGroupedValueConflict(terms, (t) => t.kind === "state" && t.type === "modifier" ? t : null, (t) => t.attribute, (t) => t.value)) return true;
308
- if (hasNestedModifierConflict(terms, "root")) return true;
309
- if (hasNestedModifierConflict(terms, "own")) return true;
310
- return false;
311
- }
312
- /**
313
- * Collect modifier conditions inside non-negated state wrappers of `kind`
314
- * and check for the same value-conflict pattern as the top-level pass.
315
- *
316
- * Modifiers from multiple sibling wrappers are combined — both wrappers
317
- * scope to the same element (one :root, one own scope), so an attribute
318
- * conflict across wrappers is still impossible.
319
- */
320
- function hasNestedModifierConflict(terms, wrapperType) {
321
- const innerTerms = [];
322
- for (const term of terms) if (term.kind === "state" && term.type === wrapperType && !term.negated) flattenAndIntoArray(term.innerCondition, innerTerms);
323
- if (innerTerms.length < 2) return false;
324
- return hasGroupedValueConflict(innerTerms, (t) => t.kind === "state" && t.type === "modifier" ? t : null, (t) => t.attribute, (t) => t.value);
325
- }
326
- /**
327
- * Flatten a top-level AND tree into a flat list of conjuncts. Non-AND nodes
328
- * are pushed as-is.
329
- */
330
- function flattenAndIntoArray(node, into) {
331
- if (node.kind === "compound" && node.operator === "AND") for (const child of node.children) flattenAndIntoArray(child, into);
332
- else into.push(node);
333
- }
334
- function hasContainerStyleConflict(terms) {
335
- return hasGroupedValueConflict(terms, (t) => t.kind === "state" && t.type === "container" && t.subtype === "style" ? t : null, (t) => `${t.containerName || "_"}:${t.property}`, (t) => t.propertyValue);
336
- }
337
- /**
338
- * Remove negations that are implied by positive terms.
339
- *
340
- * Key optimizations:
341
- * 1. style(--variant: danger) implies NOT style(--variant: success)
342
- * → If we have style(--variant: danger) & not style(--variant: success),
343
- * the negation is redundant and can be removed.
344
- *
345
- * 2. [data-theme="dark"] implies NOT [data-theme="light"]
346
- * → Same logic for attribute selectors.
347
- *
348
- * This produces cleaner CSS:
349
- * Before: @container style(--variant: danger) and (not style(--variant: success))
350
- * After: @container style(--variant: danger)
351
- */
352
- /**
353
- * Collect positive values from terms and build a "is this negation implied?" check.
354
- *
355
- * A negation is implied (redundant) when a positive term for the same group
356
- * already pins a specific value, making "NOT other-value" obvious.
357
- * e.g. style(--variant: danger) implies NOT style(--variant: success).
358
- */
359
- function buildImpliedNegationCheck(terms) {
360
- const positiveValues = /* @__PURE__ */ new Map();
361
- for (const term of terms) {
362
- if (term.kind !== "state" || term.negated) continue;
363
- if (term.type === "container" && term.subtype === "style") {
364
- if (term.propertyValue !== void 0) positiveValues.set(`c:${term.containerName || "_"}:${term.property}`, term.propertyValue);
365
- } else if (term.type === "modifier" && term.value !== void 0) positiveValues.set(`m:${term.attribute}`, term.value);
366
- }
367
- return (term) => {
368
- if (term.kind !== "state" || !term.negated) return false;
369
- if (term.type === "container" && term.subtype === "style") {
370
- if (term.propertyValue === void 0) return false;
371
- const pos = positiveValues.get(`c:${term.containerName || "_"}:${term.property}`);
372
- return pos !== void 0 && term.propertyValue !== pos;
373
- }
374
- if (term.type === "modifier" && term.value !== void 0) {
375
- const pos = positiveValues.get(`m:${term.attribute}`);
376
- return pos !== void 0 && term.value !== pos;
377
- }
378
- return false;
379
- };
380
- }
381
- function removeImpliedNegations(terms) {
382
- const isImplied = buildImpliedNegationCheck(terms);
383
- return terms.filter((t) => !isImplied(t));
384
- }
385
- function deduplicateTerms(terms) {
386
- const seen = /* @__PURE__ */ new Set();
387
- const result = [];
388
- for (const term of terms) {
389
- const id = getConditionUniqueId(term);
390
- if (!seen.has(id)) {
391
- seen.add(id);
392
- result.push(term);
393
- }
394
- }
395
- return result;
396
- }
397
- /**
398
- * Merge compatible range conditions
399
- * e.g., @media(w >= 400px) & @media(w <= 800px) → @media(400px <= w <= 800px)
400
- */
401
- function mergeRanges(terms) {
402
- const mediaByDim = /* @__PURE__ */ new Map();
403
- const containerByDim = /* @__PURE__ */ new Map();
404
- terms.forEach((term, index) => {
405
- if (term.kind !== "state") return;
406
- if (term.type === "media" && term.subtype === "dimension" && !term.negated) {
407
- const key = term.dimension || "width";
408
- if (!mediaByDim.has(key)) mediaByDim.set(key, {
409
- conditions: [],
410
- indices: []
411
- });
412
- const group = mediaByDim.get(key);
413
- group.conditions.push(term);
414
- group.indices.push(index);
415
- }
416
- if (term.type === "container" && term.subtype === "dimension" && !term.negated) {
417
- const key = `${term.containerName || "_"}:${term.dimension || "width"}`;
418
- if (!containerByDim.has(key)) containerByDim.set(key, {
419
- conditions: [],
420
- indices: []
421
- });
422
- const group = containerByDim.get(key);
423
- group.conditions.push(term);
424
- group.indices.push(index);
425
- }
426
- });
427
- const indicesToRemove = /* @__PURE__ */ new Set();
428
- const mergedTerms = [];
429
- for (const [_dim, group] of mediaByDim) if (group.conditions.length > 1) {
430
- const merged = mergeMediaRanges(group.conditions);
431
- if (merged) {
432
- group.indices.forEach((i) => indicesToRemove.add(i));
433
- mergedTerms.push(merged);
434
- }
435
- }
436
- for (const [, group] of containerByDim) if (group.conditions.length > 1) {
437
- const merged = mergeContainerRanges(group.conditions);
438
- if (merged) {
439
- group.indices.forEach((i) => indicesToRemove.add(i));
440
- mergedTerms.push(merged);
441
- }
442
- }
443
- const result = [];
444
- terms.forEach((term, index) => {
445
- if (!indicesToRemove.has(index)) result.push(term);
446
- });
447
- result.push(...mergedTerms);
448
- return result;
449
- }
450
- /**
451
- * Tighten bounds by picking the most restrictive lower and upper bounds
452
- * from a set of conditions that have lowerBound/upperBound fields.
453
- */
454
- function tightenBounds(conditions) {
455
- let lowerBound;
456
- let upperBound;
457
- for (const cond of conditions) {
458
- if (cond.lowerBound) {
459
- if (!lowerBound || (cond.lowerBound.valueNumeric ?? -Infinity) > (lowerBound.valueNumeric ?? -Infinity)) lowerBound = cond.lowerBound;
460
- }
461
- if (cond.upperBound) {
462
- if (!upperBound || (cond.upperBound.valueNumeric ?? Infinity) < (upperBound.valueNumeric ?? Infinity)) upperBound = cond.upperBound;
463
- }
464
- }
465
- return {
466
- lowerBound,
467
- upperBound
468
- };
469
- }
470
- function appendBoundsToUniqueId(parts, lowerBound, upperBound) {
471
- if (lowerBound) {
472
- parts.push(lowerBound.inclusive ? ">=" : ">");
473
- parts.push(lowerBound.value);
474
- }
475
- if (upperBound) {
476
- parts.push(upperBound.inclusive ? "<=" : "<");
477
- parts.push(upperBound.value);
478
- }
479
- }
480
- function mergeDimensionRanges(conditions, idPrefix) {
481
- if (conditions.length === 0) return null;
482
- const { lowerBound, upperBound } = tightenBounds(conditions);
483
- const base = conditions[0];
484
- const parts = [...idPrefix];
485
- appendBoundsToUniqueId(parts, lowerBound, upperBound);
486
- return {
487
- ...base,
488
- negated: false,
489
- raw: buildMergedRaw(base.dimension || "width", lowerBound, upperBound),
490
- uniqueId: parts.join(":"),
491
- lowerBound,
492
- upperBound
493
- };
494
- }
495
- function mergeMediaRanges(conditions) {
496
- return mergeDimensionRanges(conditions, [
497
- "media",
498
- "dim",
499
- conditions[0]?.dimension ?? "width"
500
- ]);
501
- }
502
- function mergeContainerRanges(conditions) {
503
- const base = conditions[0];
504
- if (!base) return null;
505
- return mergeDimensionRanges(conditions, [
506
- "container",
507
- "dim",
508
- base.containerName || "_",
509
- base.dimension ?? "width"
510
- ]);
511
- }
512
- function buildMergedRaw(dimension, lowerBound, upperBound) {
513
- if (lowerBound && upperBound) {
514
- const lowerOp = lowerBound.inclusive ? "<=" : "<";
515
- const upperOp = upperBound.inclusive ? "<=" : "<";
516
- return `@media(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;
517
- } else if (upperBound) return `@media(${dimension} ${upperBound.inclusive ? "<=" : "<"} ${upperBound.value})`;
518
- else if (lowerBound) return `@media(${dimension} ${lowerBound.inclusive ? ">=" : ">"} ${lowerBound.value})`;
519
- return "@media()";
520
- }
521
- /**
522
- * Apply complementary factoring: (A & B) | (A & !B) → A
523
- *
524
- * Finds pairs of AND compounds that share all children except one,
525
- * where the differing child is complementary (X vs !X).
526
- * Replaces the pair with the common terms.
527
- *
528
- * This is applied iteratively until no more reductions are possible,
529
- * since factoring can expose further simplification opportunities.
530
- */
531
- function applyComplementaryFactoring(terms) {
532
- let changed = true;
533
- while (changed) {
534
- changed = false;
535
- for (let i = 0; i < terms.length; i++) {
536
- const a = terms[i];
537
- if (a.kind !== "compound" || a.operator !== "AND") continue;
538
- for (let j = i + 1; j < terms.length; j++) {
539
- const b = terms[j];
540
- if (b.kind !== "compound" || b.operator !== "AND") continue;
541
- const factored = tryFactorPair(a.children, b.children);
542
- if (factored) {
543
- const replacement = simplifyInner(factored);
544
- terms = [
545
- ...terms.slice(0, i),
546
- ...terms.slice(i + 1, j),
547
- ...terms.slice(j + 1),
548
- replacement
549
- ];
550
- changed = true;
551
- break;
552
- }
553
- }
554
- if (changed) break;
555
- }
556
- }
557
- return terms;
558
- }
559
- /**
560
- * Try to factor two AND children lists.
561
- *
562
- * Extracts the common children (by uniqueId). If the remaining
563
- * (non-common) parts of each side OR to TRUE, the common part alone
564
- * is sufficient: `(common & restA) | (common & restB) → common`
565
- * when `restA | restB → TRUE`.
566
- *
567
- * Also handles the simpler case where exactly one child is
568
- * complementary: `[A, B, C]` and `[A, !B, C]` → `AND(A, C)`.
569
- */
570
- function tryFactorPair(aChildren, bChildren) {
571
- const aIds = aChildren.map((c) => getConditionUniqueId(c));
572
- const bIds = bChildren.map((c) => getConditionUniqueId(c));
573
- const bIdSet = new Set(bIds);
574
- const aIdSet = new Set(aIds);
575
- const commonIndicesA = [];
576
- const restIndicesA = [];
577
- for (let i = 0; i < aIds.length; i++) if (bIdSet.has(aIds[i])) commonIndicesA.push(i);
578
- else restIndicesA.push(i);
579
- const restIndicesB = [];
580
- for (let i = 0; i < bIds.length; i++) if (!aIdSet.has(bIds[i])) restIndicesB.push(i);
581
- if (commonIndicesA.length === 0) return null;
582
- if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;
583
- const restA = restIndicesA.length === 0 ? trueCondition() : restIndicesA.length === 1 ? aChildren[restIndicesA[0]] : and(...restIndicesA.map((i) => aChildren[i]));
584
- const restB = restIndicesB.length === 0 ? trueCondition() : restIndicesB.length === 1 ? bChildren[restIndicesB[0]] : and(...restIndicesB.map((i) => bChildren[i]));
585
- if (simplifyInner({
586
- kind: "compound",
587
- operator: "OR",
588
- children: [restA, restB]
589
- }).kind !== "true") {
590
- const simplifiedRestB = simplifyInner(restB);
591
- if (getConditionUniqueId(simplifyInner(not(restA))) !== getConditionUniqueId(simplifiedRestB)) return null;
592
- }
593
- const common = commonIndicesA.map((i) => aChildren[i]);
594
- if (common.length === 0) return trueCondition();
595
- if (common.length === 1) return common[0];
596
- return and(...common);
597
- }
598
- function sortTerms(terms) {
599
- const withIds = terms.map((t) => [getConditionUniqueId(t), t]);
600
- withIds.sort((a, b) => a[0].localeCompare(b[0]));
601
- return withIds.map(([, t]) => t);
602
- }
603
- /**
604
- * Apply the absorption law: removes compound terms that are absorbed by
605
- * another term already present (simple or compound).
606
- *
607
- * For AND context: A & (A | B) → A (absorbs OR compounds)
608
- * For OR context: A | (A & B) → A (absorbs AND compounds)
609
- *
610
- * After flattening, a compound A = OR(X, Y) becomes [X, Y, ...] in the
611
- * outer OR. A child AND(A, B) = AND(OR(X, Y), B) still references the
612
- * original un-flattened compound. We reconstruct possible compound
613
- * absorbers from the flattened terms so absorption works across nesting.
614
- */
615
- function applyAbsorption(terms, absorbedOperator) {
616
- const absorberIds = /* @__PURE__ */ new Set();
617
- for (const term of terms) absorberIds.add(getConditionUniqueId(term));
618
- let changed = true;
619
- while (changed) {
620
- changed = false;
621
- for (const term of terms) {
622
- if (term.kind !== "compound" || term.operator !== absorbedOperator) continue;
623
- for (const child of term.children) {
624
- if (child.kind !== "compound") continue;
625
- const childId = getConditionUniqueId(child);
626
- if (absorberIds.has(childId)) continue;
627
- if (child.children.every((c) => absorberIds.has(getConditionUniqueId(c)))) {
628
- absorberIds.add(childId);
629
- changed = true;
630
- }
631
- }
632
- }
633
- }
634
- return terms.filter((term) => {
635
- if (term.kind === "compound" && term.operator === absorbedOperator) {
636
- for (const child of term.children) if (absorberIds.has(getConditionUniqueId(child))) return false;
637
- }
638
- return true;
639
- });
640
- }
641
- function applyAbsorptionAnd(terms) {
642
- return applyAbsorption(terms, "OR");
643
- }
644
- function applyAbsorptionOr(terms) {
645
- return applyAbsorption(terms, "AND");
646
- }
647
- /**
648
- * Apply the consensus/resolution rule for AND:
649
- * (A | B) & (A | !B) → A
650
- *
651
- * This is the dual of complementary factoring in OR context:
652
- * (A & B) | (A & !B) → A
653
- *
654
- * Extracts common children from two OR terms. If the remaining
655
- * parts of each side AND to FALSE, the common part alone is
656
- * sufficient.
657
- */
658
- function applyConsensusAnd(terms) {
659
- let changed = true;
660
- while (changed) {
661
- changed = false;
662
- for (let i = 0; i < terms.length; i++) {
663
- const a = terms[i];
664
- if (a.kind !== "compound" || a.operator !== "OR") continue;
665
- for (let j = i + 1; j < terms.length; j++) {
666
- const b = terms[j];
667
- if (b.kind !== "compound" || b.operator !== "OR") continue;
668
- const resolved = tryResolvePair(a.children, b.children);
669
- if (resolved) {
670
- const replacement = simplifyInner(resolved);
671
- terms = [
672
- ...terms.slice(0, i),
673
- ...terms.slice(i + 1, j),
674
- ...terms.slice(j + 1),
675
- replacement
676
- ];
677
- changed = true;
678
- break;
679
- }
680
- }
681
- if (changed) break;
682
- }
683
- }
684
- return terms;
685
- }
686
- /**
687
- * Try to resolve two OR children lists.
688
- *
689
- * Extracts common children (by uniqueId). If the remaining
690
- * (non-common) parts AND to FALSE, the common part alone
691
- * is sufficient: `(common | restA) & (common | restB) → common`
692
- * when `restA & restB → FALSE`.
693
- */
694
- function tryResolvePair(aChildren, bChildren) {
695
- const aIds = aChildren.map((c) => getConditionUniqueId(c));
696
- const bIds = bChildren.map((c) => getConditionUniqueId(c));
697
- const bIdSet = new Set(bIds);
698
- const aIdSet = new Set(aIds);
699
- const commonIndicesA = [];
700
- const restIndicesA = [];
701
- for (let i = 0; i < aIds.length; i++) if (bIdSet.has(aIds[i])) commonIndicesA.push(i);
702
- else restIndicesA.push(i);
703
- const restIndicesB = [];
704
- for (let i = 0; i < bIds.length; i++) if (!aIdSet.has(bIds[i])) restIndicesB.push(i);
705
- if (commonIndicesA.length === 0) return null;
706
- if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;
707
- const restA = restIndicesA.length === 0 ? falseCondition() : restIndicesA.length === 1 ? aChildren[restIndicesA[0]] : or(...restIndicesA.map((i) => aChildren[i]));
708
- const restB = restIndicesB.length === 0 ? falseCondition() : restIndicesB.length === 1 ? bChildren[restIndicesB[0]] : or(...restIndicesB.map((i) => bChildren[i]));
709
- if (simplifyInner({
710
- kind: "compound",
711
- operator: "AND",
712
- children: [restA, restB]
713
- }).kind !== "false") {
714
- const simplifiedRestB = simplifyInner(restB);
715
- if (getConditionUniqueId(simplifyInner(not(restA))) !== getConditionUniqueId(simplifiedRestB)) return null;
716
- }
717
- const common = commonIndicesA.map((i) => aChildren[i]);
718
- if (common.length === 0) return falseCondition();
719
- if (common.length === 1) return common[0];
720
- return or(...common);
721
- }
722
- //#endregion
723
- export { simplifyCondition };
724
-
725
- //# sourceMappingURL=simplify.js.map