@tenphi/tasty 2.0.3 → 2.0.4

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 (322) 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.d.ts → collector-CkZ517g4.d.ts} +3 -3
  4. package/dist/{ssr/collector.js → collector-DXqvGOb1.js} +5 -10
  5. package/dist/collector-DXqvGOb1.js.map +1 -0
  6. package/dist/config-5jzS6k6B.js +10005 -0
  7. package/dist/config-5jzS6k6B.js.map +1 -0
  8. package/dist/config-DknGsfMo.d.ts +857 -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 +5 -26
  13. package/dist/core-CtU6-9OC.js +1507 -0
  14. package/dist/core-CtU6-9OC.js.map +1 -0
  15. package/dist/{zero/extractor.js → css-writer-DHkX0JuE.js} +74 -11
  16. package/dist/css-writer-DHkX0JuE.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-DH13ewDu.js +143 -0
  20. package/dist/format-rules-DH13ewDu.js.map +1 -0
  21. package/dist/{ssr/hydrate.js → hydrate-C1Gv-DoS.js} +3 -3
  22. package/dist/hydrate-C1Gv-DoS.js.map +1 -0
  23. package/dist/{styles/types.d.ts → index-PzENbpAq.d.ts} +701 -5
  24. package/dist/index-o7zV2yCr.d.ts +1561 -0
  25. package/dist/index.d.ts +5 -51
  26. package/dist/index.js +728 -35
  27. package/dist/index.js.map +1 -0
  28. package/dist/keyframes-b7X3UxDV.js +587 -0
  29. package/dist/keyframes-b7X3UxDV.js.map +1 -0
  30. package/dist/{utils/merge-styles.d.ts → merge-styles-C7KTy7MY.d.ts} +3 -3
  31. package/dist/{utils/merge-styles.js → merge-styles-Tgo3BbL2.js} +3 -4
  32. package/dist/merge-styles-Tgo3BbL2.js.map +1 -0
  33. package/dist/{utils/resolve-recipes.js → resolve-recipes-Ca2-5CxM.js} +4 -6
  34. package/dist/resolve-recipes-Ca2-5CxM.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/package.json +3 -3
  51. package/dist/_virtual/_rolldown/runtime.js +0 -7
  52. package/dist/chunks/cacheKey.d.ts +0 -1
  53. package/dist/chunks/cacheKey.js +0 -77
  54. package/dist/chunks/cacheKey.js.map +0 -1
  55. package/dist/chunks/definitions.d.ts +0 -37
  56. package/dist/chunks/definitions.js +0 -258
  57. package/dist/chunks/definitions.js.map +0 -1
  58. package/dist/chunks/index.d.ts +0 -1
  59. package/dist/chunks/renderChunk.d.ts +0 -1
  60. package/dist/chunks/renderChunk.js +0 -59
  61. package/dist/chunks/renderChunk.js.map +0 -1
  62. package/dist/compute-styles.d.ts +0 -31
  63. package/dist/compute-styles.js +0 -322
  64. package/dist/compute-styles.js.map +0 -1
  65. package/dist/config.d.ts +0 -407
  66. package/dist/config.js +0 -591
  67. package/dist/config.js.map +0 -1
  68. package/dist/counter-style/index.js +0 -51
  69. package/dist/counter-style/index.js.map +0 -1
  70. package/dist/debug.d.ts +0 -89
  71. package/dist/debug.js +0 -453
  72. package/dist/debug.js.map +0 -1
  73. package/dist/font-face/index.js +0 -63
  74. package/dist/font-face/index.js.map +0 -1
  75. package/dist/hooks/index.d.ts +0 -7
  76. package/dist/hooks/useCounterStyle.d.ts +0 -36
  77. package/dist/hooks/useCounterStyle.js +0 -65
  78. package/dist/hooks/useCounterStyle.js.map +0 -1
  79. package/dist/hooks/useFontFace.d.ts +0 -45
  80. package/dist/hooks/useFontFace.js +0 -66
  81. package/dist/hooks/useFontFace.js.map +0 -1
  82. package/dist/hooks/useGlobalStyles.d.ts +0 -46
  83. package/dist/hooks/useGlobalStyles.js +0 -88
  84. package/dist/hooks/useGlobalStyles.js.map +0 -1
  85. package/dist/hooks/useKeyframes.d.ts +0 -58
  86. package/dist/hooks/useKeyframes.js +0 -55
  87. package/dist/hooks/useKeyframes.js.map +0 -1
  88. package/dist/hooks/useProperty.d.ts +0 -81
  89. package/dist/hooks/useProperty.js +0 -96
  90. package/dist/hooks/useProperty.js.map +0 -1
  91. package/dist/hooks/useRawCSS.d.ts +0 -22
  92. package/dist/hooks/useRawCSS.js +0 -103
  93. package/dist/hooks/useRawCSS.js.map +0 -1
  94. package/dist/hooks/useStyles.d.ts +0 -40
  95. package/dist/hooks/useStyles.js +0 -31
  96. package/dist/hooks/useStyles.js.map +0 -1
  97. package/dist/injector/index.d.ts +0 -182
  98. package/dist/injector/index.js +0 -185
  99. package/dist/injector/index.js.map +0 -1
  100. package/dist/injector/injector.d.ts +0 -198
  101. package/dist/injector/injector.js +0 -651
  102. package/dist/injector/injector.js.map +0 -1
  103. package/dist/injector/sheet-manager.d.ts +0 -132
  104. package/dist/injector/sheet-manager.js +0 -699
  105. package/dist/injector/sheet-manager.js.map +0 -1
  106. package/dist/injector/types.d.ts +0 -235
  107. package/dist/keyframes/index.js +0 -206
  108. package/dist/keyframes/index.js.map +0 -1
  109. package/dist/parser/classify.js +0 -319
  110. package/dist/parser/classify.js.map +0 -1
  111. package/dist/parser/const.js +0 -60
  112. package/dist/parser/const.js.map +0 -1
  113. package/dist/parser/lru.js +0 -109
  114. package/dist/parser/lru.js.map +0 -1
  115. package/dist/parser/parser.d.ts +0 -25
  116. package/dist/parser/parser.js +0 -115
  117. package/dist/parser/parser.js.map +0 -1
  118. package/dist/parser/tokenizer.js +0 -69
  119. package/dist/parser/tokenizer.js.map +0 -1
  120. package/dist/parser/types.d.ts +0 -51
  121. package/dist/parser/types.js +0 -46
  122. package/dist/parser/types.js.map +0 -1
  123. package/dist/pipeline/conditions.d.ts +0 -134
  124. package/dist/pipeline/conditions.js +0 -406
  125. package/dist/pipeline/conditions.js.map +0 -1
  126. package/dist/pipeline/exclusive.js +0 -389
  127. package/dist/pipeline/exclusive.js.map +0 -1
  128. package/dist/pipeline/index.d.ts +0 -55
  129. package/dist/pipeline/index.js +0 -749
  130. package/dist/pipeline/index.js.map +0 -1
  131. package/dist/pipeline/materialize-contradictions.js +0 -125
  132. package/dist/pipeline/materialize-contradictions.js.map +0 -1
  133. package/dist/pipeline/materialize.js +0 -1038
  134. package/dist/pipeline/materialize.js.map +0 -1
  135. package/dist/pipeline/parseStateKey.d.ts +0 -15
  136. package/dist/pipeline/parseStateKey.js +0 -446
  137. package/dist/pipeline/parseStateKey.js.map +0 -1
  138. package/dist/pipeline/simplify.js +0 -725
  139. package/dist/pipeline/simplify.js.map +0 -1
  140. package/dist/pipeline/warnings.js +0 -18
  141. package/dist/pipeline/warnings.js.map +0 -1
  142. package/dist/plugins/index.d.ts +0 -2
  143. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  144. package/dist/plugins/okhsl-plugin.js +0 -97
  145. package/dist/plugins/okhsl-plugin.js.map +0 -1
  146. package/dist/plugins/types.d.ts +0 -87
  147. package/dist/properties/index.js +0 -222
  148. package/dist/properties/index.js.map +0 -1
  149. package/dist/properties/property-type-resolver.d.ts +0 -24
  150. package/dist/properties/property-type-resolver.js +0 -90
  151. package/dist/properties/property-type-resolver.js.map +0 -1
  152. package/dist/rsc-cache.js +0 -79
  153. package/dist/rsc-cache.js.map +0 -1
  154. package/dist/ssr/async-storage.d.ts +0 -17
  155. package/dist/ssr/async-storage.js.map +0 -1
  156. package/dist/ssr/collect-auto-properties.js +0 -58
  157. package/dist/ssr/collect-auto-properties.js.map +0 -1
  158. package/dist/ssr/collector.js.map +0 -1
  159. package/dist/ssr/context.js.map +0 -1
  160. package/dist/ssr/format-global-rules.js.map +0 -1
  161. package/dist/ssr/format-keyframes.js +0 -69
  162. package/dist/ssr/format-keyframes.js.map +0 -1
  163. package/dist/ssr/format-property.js +0 -49
  164. package/dist/ssr/format-property.js.map +0 -1
  165. package/dist/ssr/format-rules.js +0 -73
  166. package/dist/ssr/format-rules.js.map +0 -1
  167. package/dist/ssr/hydrate.d.ts +0 -29
  168. package/dist/ssr/hydrate.js.map +0 -1
  169. package/dist/ssr/ssr-collector-ref.js +0 -29
  170. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  171. package/dist/states/index.d.ts +0 -49
  172. package/dist/states/index.js +0 -170
  173. package/dist/states/index.js.map +0 -1
  174. package/dist/static/tastyStatic.d.ts +0 -46
  175. package/dist/static/tastyStatic.js +0 -30
  176. package/dist/static/tastyStatic.js.map +0 -1
  177. package/dist/static/types.d.ts +0 -49
  178. package/dist/static/types.js +0 -24
  179. package/dist/static/types.js.map +0 -1
  180. package/dist/styles/border.d.ts +0 -25
  181. package/dist/styles/border.js +0 -120
  182. package/dist/styles/border.js.map +0 -1
  183. package/dist/styles/color.d.ts +0 -14
  184. package/dist/styles/color.js +0 -26
  185. package/dist/styles/color.js.map +0 -1
  186. package/dist/styles/const.js +0 -17
  187. package/dist/styles/const.js.map +0 -1
  188. package/dist/styles/createStyle.js +0 -79
  189. package/dist/styles/createStyle.js.map +0 -1
  190. package/dist/styles/dimension.js +0 -109
  191. package/dist/styles/dimension.js.map +0 -1
  192. package/dist/styles/directional.js +0 -133
  193. package/dist/styles/directional.js.map +0 -1
  194. package/dist/styles/display.d.ts +0 -30
  195. package/dist/styles/display.js +0 -73
  196. package/dist/styles/display.js.map +0 -1
  197. package/dist/styles/fade.d.ts +0 -15
  198. package/dist/styles/fade.js +0 -62
  199. package/dist/styles/fade.js.map +0 -1
  200. package/dist/styles/fill.d.ts +0 -42
  201. package/dist/styles/fill.js +0 -51
  202. package/dist/styles/fill.js.map +0 -1
  203. package/dist/styles/flow.d.ts +0 -16
  204. package/dist/styles/flow.js +0 -12
  205. package/dist/styles/flow.js.map +0 -1
  206. package/dist/styles/gap.d.ts +0 -31
  207. package/dist/styles/gap.js +0 -38
  208. package/dist/styles/gap.js.map +0 -1
  209. package/dist/styles/height.d.ts +0 -17
  210. package/dist/styles/height.js +0 -19
  211. package/dist/styles/height.js.map +0 -1
  212. package/dist/styles/index.d.ts +0 -1
  213. package/dist/styles/index.js +0 -8
  214. package/dist/styles/index.js.map +0 -1
  215. package/dist/styles/inset.d.ts +0 -24
  216. package/dist/styles/inset.js +0 -34
  217. package/dist/styles/inset.js.map +0 -1
  218. package/dist/styles/list.d.ts +0 -16
  219. package/dist/styles/list.js +0 -100
  220. package/dist/styles/list.js.map +0 -1
  221. package/dist/styles/margin.d.ts +0 -24
  222. package/dist/styles/margin.js +0 -32
  223. package/dist/styles/margin.js.map +0 -1
  224. package/dist/styles/outline.d.ts +0 -29
  225. package/dist/styles/outline.js +0 -55
  226. package/dist/styles/outline.js.map +0 -1
  227. package/dist/styles/padding.d.ts +0 -24
  228. package/dist/styles/padding.js +0 -32
  229. package/dist/styles/padding.js.map +0 -1
  230. package/dist/styles/placement.d.ts +0 -37
  231. package/dist/styles/placement.js +0 -74
  232. package/dist/styles/placement.js.map +0 -1
  233. package/dist/styles/predefined.d.ts +0 -71
  234. package/dist/styles/predefined.js +0 -237
  235. package/dist/styles/predefined.js.map +0 -1
  236. package/dist/styles/preset.d.ts +0 -52
  237. package/dist/styles/preset.js +0 -127
  238. package/dist/styles/preset.js.map +0 -1
  239. package/dist/styles/radius.d.ts +0 -12
  240. package/dist/styles/radius.js +0 -83
  241. package/dist/styles/radius.js.map +0 -1
  242. package/dist/styles/scrollMargin.d.ts +0 -24
  243. package/dist/styles/scrollMargin.js +0 -32
  244. package/dist/styles/scrollMargin.js.map +0 -1
  245. package/dist/styles/scrollbar.d.ts +0 -25
  246. package/dist/styles/scrollbar.js +0 -51
  247. package/dist/styles/scrollbar.js.map +0 -1
  248. package/dist/styles/shadow.d.ts +0 -14
  249. package/dist/styles/shadow.js +0 -25
  250. package/dist/styles/shadow.js.map +0 -1
  251. package/dist/styles/shared.js +0 -17
  252. package/dist/styles/shared.js.map +0 -1
  253. package/dist/styles/transition.d.ts +0 -14
  254. package/dist/styles/transition.js +0 -159
  255. package/dist/styles/transition.js.map +0 -1
  256. package/dist/styles/width.d.ts +0 -17
  257. package/dist/styles/width.js +0 -19
  258. package/dist/styles/width.js.map +0 -1
  259. package/dist/tasty.d.ts +0 -134
  260. package/dist/tasty.js +0 -248
  261. package/dist/tasty.js.map +0 -1
  262. package/dist/types.d.ts +0 -184
  263. package/dist/utils/cache-wrapper.js +0 -21
  264. package/dist/utils/cache-wrapper.js.map +0 -1
  265. package/dist/utils/case-converter.js +0 -8
  266. package/dist/utils/case-converter.js.map +0 -1
  267. package/dist/utils/color-math.d.ts +0 -46
  268. package/dist/utils/color-math.js +0 -749
  269. package/dist/utils/color-math.js.map +0 -1
  270. package/dist/utils/color-space.d.ts +0 -5
  271. package/dist/utils/color-space.js +0 -228
  272. package/dist/utils/color-space.js.map +0 -1
  273. package/dist/utils/colors.d.ts +0 -5
  274. package/dist/utils/colors.js +0 -10
  275. package/dist/utils/colors.js.map +0 -1
  276. package/dist/utils/css-types.d.ts +0 -7
  277. package/dist/utils/deps-equal.js +0 -15
  278. package/dist/utils/deps-equal.js.map +0 -1
  279. package/dist/utils/dotize.d.ts +0 -26
  280. package/dist/utils/dotize.js +0 -122
  281. package/dist/utils/dotize.js.map +0 -1
  282. package/dist/utils/filter-base-props.d.ts +0 -15
  283. package/dist/utils/filter-base-props.js +0 -45
  284. package/dist/utils/filter-base-props.js.map +0 -1
  285. package/dist/utils/get-display-name.d.ts +0 -7
  286. package/dist/utils/get-display-name.js +0 -10
  287. package/dist/utils/get-display-name.js.map +0 -1
  288. package/dist/utils/has-keys.js +0 -13
  289. package/dist/utils/has-keys.js.map +0 -1
  290. package/dist/utils/hash.js +0 -14
  291. package/dist/utils/hash.js.map +0 -1
  292. package/dist/utils/is-dev-env.js +0 -19
  293. package/dist/utils/is-dev-env.js.map +0 -1
  294. package/dist/utils/is-valid-element-type.js +0 -15
  295. package/dist/utils/is-valid-element-type.js.map +0 -1
  296. package/dist/utils/merge-styles.js.map +0 -1
  297. package/dist/utils/mod-attrs.d.ts +0 -6
  298. package/dist/utils/mod-attrs.js +0 -20
  299. package/dist/utils/mod-attrs.js.map +0 -1
  300. package/dist/utils/process-tokens.d.ts +0 -17
  301. package/dist/utils/process-tokens.js +0 -83
  302. package/dist/utils/process-tokens.js.map +0 -1
  303. package/dist/utils/resolve-recipes.d.ts +0 -17
  304. package/dist/utils/resolve-recipes.js.map +0 -1
  305. package/dist/utils/selector-transform.js +0 -32
  306. package/dist/utils/selector-transform.js.map +0 -1
  307. package/dist/utils/string.js +0 -8
  308. package/dist/utils/string.js.map +0 -1
  309. package/dist/utils/styles.d.ts +0 -99
  310. package/dist/utils/styles.js +0 -220
  311. package/dist/utils/styles.js.map +0 -1
  312. package/dist/utils/typography.d.ts +0 -58
  313. package/dist/utils/typography.js +0 -51
  314. package/dist/utils/typography.js.map +0 -1
  315. package/dist/utils/warnings.d.ts +0 -16
  316. package/dist/utils/warnings.js +0 -16
  317. package/dist/utils/warnings.js.map +0 -1
  318. package/dist/zero/css-writer.d.ts +0 -45
  319. package/dist/zero/css-writer.js +0 -73
  320. package/dist/zero/css-writer.js.map +0 -1
  321. package/dist/zero/extractor.d.ts +0 -24
  322. 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