@veltra/desktop 1.1.14 → 1.1.18

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 (277) hide show
  1. package/dist/components/action/action-group.vue.d.ts +1 -1
  2. package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/action/action.js.map +1 -1
  4. package/dist/components/action/action.vue.d.ts +1 -1
  5. package/dist/components/action/style2.css +0 -4
  6. package/dist/components/auto-complete/auto-complete.js.map +1 -1
  7. package/dist/components/auto-complete/style.js +1 -1
  8. package/dist/components/auto-complete/use-keyboard.js.map +1 -1
  9. package/dist/components/auto-complete/use-suggestions.js.map +1 -1
  10. package/dist/components/badge/badge.js +1 -1
  11. package/dist/components/badge/badge.js.map +1 -1
  12. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  13. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  14. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  15. package/dist/components/batch-edit/helper.js.map +1 -1
  16. package/dist/components/batch-edit/style.js +1 -1
  17. package/dist/components/batch-edit/use-edit.js.map +1 -1
  18. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  19. package/dist/components/button/button-group.js.map +1 -1
  20. package/dist/components/button/button.js.map +1 -1
  21. package/dist/components/calendar/calendar.js.map +1 -1
  22. package/dist/components/calendar/utils.js.map +1 -1
  23. package/dist/components/card/card-action.js.map +1 -1
  24. package/dist/components/card/card-content.js.map +1 -1
  25. package/dist/components/card/card-cover.js.map +1 -1
  26. package/dist/components/card/card-header.js.map +1 -1
  27. package/dist/components/card/card.js.map +1 -1
  28. package/dist/components/cascade/cascade-panel-item.js.map +1 -1
  29. package/dist/components/cascade/cascade.js.map +1 -1
  30. package/dist/components/cascade/cascade.vue.d.ts +3 -3
  31. package/dist/components/cascade/node.js.map +1 -1
  32. package/dist/components/cascade/use-check.js.map +1 -1
  33. package/dist/components/cascade/use-data-map.js.map +1 -1
  34. package/dist/components/cascade/use-select.js +1 -1
  35. package/dist/components/cascade/use-select.js.map +1 -1
  36. package/dist/components/check-tag/check-tag.js.map +1 -1
  37. package/dist/components/checkbox/checkbox-button.js.map +1 -1
  38. package/dist/components/checkbox/checkbox.js.map +1 -1
  39. package/dist/components/checkbox/style.js +1 -1
  40. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  41. package/dist/components/code-editor/code-editor.js.map +1 -1
  42. package/dist/components/collapse/collapse-item.js.map +1 -1
  43. package/dist/components/collapse/collapse.js.map +1 -1
  44. package/dist/components/condition-editor/components/condition-group.js +138 -103
  45. package/dist/components/condition-editor/components/condition-group.js.map +1 -1
  46. package/dist/components/condition-editor/components/condition-row.js +146 -95
  47. package/dist/components/condition-editor/components/condition-row.js.map +1 -1
  48. package/dist/components/condition-editor/condition-editor.js +18 -40
  49. package/dist/components/condition-editor/condition-editor.js.map +1 -1
  50. package/dist/components/condition-editor/condition-editor.vue.d.ts +0 -2
  51. package/dist/components/condition-editor/core/evaluator.d.ts +22 -0
  52. package/dist/components/condition-editor/core/evaluator.js +111 -50
  53. package/dist/components/condition-editor/core/evaluator.js.map +1 -1
  54. package/dist/components/condition-editor/core/operators.js.map +1 -1
  55. package/dist/components/condition-editor/index.d.ts +2 -1
  56. package/dist/components/condition-editor/style2.css +159 -82
  57. package/dist/components/context-menu/api.js.map +1 -1
  58. package/dist/components/context-menu/context-menu-item.js.map +1 -1
  59. package/dist/components/context-menu/context-menu.js.map +1 -1
  60. package/dist/components/context-menu/style.js +1 -1
  61. package/dist/components/date-panel/date-panel.js.map +1 -1
  62. package/dist/components/date-panel/headers/day.js.map +1 -1
  63. package/dist/components/date-panel/headers/month.js.map +1 -1
  64. package/dist/components/date-panel/headers/year.js.map +1 -1
  65. package/dist/components/date-panel/panels/day.js.map +1 -1
  66. package/dist/components/date-panel/panels/month.js.map +1 -1
  67. package/dist/components/date-panel/panels/year.js.map +1 -1
  68. package/dist/components/date-panel/use-date-select.js.map +1 -1
  69. package/dist/components/date-panel/use-panel-date.js.map +1 -1
  70. package/dist/components/date-panel/use-panel.js.map +1 -1
  71. package/dist/components/date-picker/date-picker.js.map +1 -1
  72. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  73. package/dist/components/dialog/dialog.js.map +1 -1
  74. package/dist/components/dialog/style.js +2 -2
  75. package/dist/components/dialog/use-maximum.js.map +1 -1
  76. package/dist/components/drawer/drawer.js.map +1 -1
  77. package/dist/components/drawer/style.js +1 -1
  78. package/dist/components/dropdown/dropdown.js +1 -0
  79. package/dist/components/dropdown/dropdown.js.map +1 -1
  80. package/dist/components/dropdown/style.js +1 -1
  81. package/dist/components/empty/empty.js.map +1 -1
  82. package/dist/components/expression-editor/components/path-preview.js.map +1 -1
  83. package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
  84. package/dist/components/expression-editor/core/chip.js.map +1 -1
  85. package/dist/components/expression-editor/core/editor.js.map +1 -1
  86. package/dist/components/expression-editor/core/mention.js.map +1 -1
  87. package/dist/components/expression-editor/core/model.js.map +1 -1
  88. package/dist/components/expression-editor/di.js.map +1 -1
  89. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  90. package/dist/components/file-picker/file-picker.js.map +1 -1
  91. package/dist/components/file-picker/helper.js.map +1 -1
  92. package/dist/components/file-viewer/file-viewer.js.map +1 -1
  93. package/dist/components/file-viewer/helper.js.map +1 -1
  94. package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -1
  95. package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
  96. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
  97. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
  98. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
  99. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
  100. package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
  101. package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
  102. package/dist/components/float-button/float-button.js.map +1 -1
  103. package/dist/components/form/dynamic-form-model.js.map +1 -1
  104. package/dist/components/form/form-model.js.map +1 -1
  105. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  106. package/dist/components/form/helper.js.map +1 -1
  107. package/dist/components/form/use-node-interceptor.js.map +1 -1
  108. package/dist/components/form-item/form-item.js.map +1 -1
  109. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +2 -1
  110. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  111. package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
  112. package/dist/components/grid/breakpoint.js.map +1 -1
  113. package/dist/components/grid/grid-item.js.map +1 -1
  114. package/dist/components/grid/grid.js.map +1 -1
  115. package/dist/components/grid/use-responsive.js.map +1 -1
  116. package/dist/components/grid-input/grid-input.js.map +1 -1
  117. package/dist/components/group-input/group-input.js.map +1 -1
  118. package/dist/components/group-input/use-group-items.js.map +1 -1
  119. package/dist/components/icon/icon.js.map +1 -1
  120. package/dist/components/index.d.ts +1 -0
  121. package/dist/components/index.js +4 -0
  122. package/dist/components/input/input.vue.d.ts +2 -2
  123. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/input/style.js +1 -1
  125. package/dist/components/kbd/kbd.js.map +1 -1
  126. package/dist/components/layout/layout-resizer.js.map +1 -1
  127. package/dist/components/layout/layout.js.map +1 -1
  128. package/dist/components/list/list-item.js.map +1 -1
  129. package/dist/components/list/list.js.map +1 -1
  130. package/dist/components/loading/directive.js.map +1 -1
  131. package/dist/components/loading/loading.js.map +1 -1
  132. package/dist/components/loading/style.js +1 -1
  133. package/dist/components/menu/helper.js.map +1 -1
  134. package/dist/components/menu/menu-item-collapsed.js.map +1 -1
  135. package/dist/components/menu/menu-item.js.map +1 -1
  136. package/dist/components/menu/menu-sub-collapsed.js.map +1 -1
  137. package/dist/components/menu/menu-sub.js.map +1 -1
  138. package/dist/components/menu/menu.js.map +1 -1
  139. package/dist/components/menu/use-menu-item.js.map +1 -1
  140. package/dist/components/menu/walk-menu-path.js.map +1 -1
  141. package/dist/components/message/helper.js.map +1 -1
  142. package/dist/components/message/message-box.js.map +1 -1
  143. package/dist/components/message/message.js.map +1 -1
  144. package/dist/components/message/message2.js.map +1 -1
  145. package/dist/components/message-confirm/message-confirm.js.map +1 -1
  146. package/dist/components/message-confirm/message-confirm2.js.map +1 -1
  147. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  148. package/dist/components/multi-select/multi-select.js.map +1 -1
  149. package/dist/components/multi-select/multi-select.vue.d.ts +1 -1
  150. package/dist/components/multi-select/style.js +1 -1
  151. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  152. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +3 -3
  153. package/dist/components/multi-tree-select/style.js +1 -1
  154. package/dist/components/node-render/node-render.js.map +1 -1
  155. package/dist/components/notification/index.js.map +1 -1
  156. package/dist/components/notification/notification.js.map +1 -1
  157. package/dist/components/notification/notification.vue.d.ts +1 -1
  158. package/dist/components/number/number.js.map +1 -1
  159. package/dist/components/number-input/number-input.js.map +1 -1
  160. package/dist/components/number-input/number-input.vue.d.ts +2 -2
  161. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  162. package/dist/components/paginator/paginator.js.map +1 -1
  163. package/dist/components/palette/color-transform.js.map +1 -1
  164. package/dist/components/palette/palette-alpha.js.map +1 -1
  165. package/dist/components/palette/palette-color-switch.js.map +1 -1
  166. package/dist/components/palette/palette-hue.js.map +1 -1
  167. package/dist/components/palette/palette-sv.js.map +1 -1
  168. package/dist/components/palette/palette.js.map +1 -1
  169. package/dist/components/palette/use-hsv.js.map +1 -1
  170. package/dist/components/password-input/password-input.js.map +1 -1
  171. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  172. package/dist/components/progress/progress.js.map +1 -1
  173. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  174. package/dist/components/radio/radio.js.map +1 -1
  175. package/dist/components/radio/style.js +1 -1
  176. package/dist/components/radio-group/radio-group.js.map +1 -1
  177. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  178. package/dist/components/rich-text-editor/toolbar.js.map +1 -1
  179. package/dist/components/scroll/scroll-bar.js +2 -0
  180. package/dist/components/scroll/scroll-bar.js.map +1 -1
  181. package/dist/components/scroll/scroll.js.map +1 -1
  182. package/dist/components/select/select.js.map +1 -1
  183. package/dist/components/select/use-keyboard.js.map +1 -1
  184. package/dist/components/select/use-options.js.map +1 -1
  185. package/dist/components/slider/slider-thumb.js.map +1 -1
  186. package/dist/components/slider/slider.js +1 -1
  187. package/dist/components/slider/slider.js.map +1 -1
  188. package/dist/components/slider/use-slider.js.map +1 -1
  189. package/dist/components/steps/steps.js.map +1 -1
  190. package/dist/components/switch/switch.js.map +1 -1
  191. package/dist/components/table/di.js.map +1 -1
  192. package/dist/components/table/node/col.js.map +1 -1
  193. package/dist/components/table/node/row.js.map +1 -1
  194. package/dist/components/table/table-body.js.map +1 -1
  195. package/dist/components/table/table-cell.js.map +1 -1
  196. package/dist/components/table/table-foot.js.map +1 -1
  197. package/dist/components/table/table-head.js.map +1 -1
  198. package/dist/components/table/table-row.js.map +1 -1
  199. package/dist/components/table/table.js.map +1 -1
  200. package/dist/components/table/use-check.js.map +1 -1
  201. package/dist/components/table/use-col-resize.js.map +1 -1
  202. package/dist/components/table/use-columns.js.map +1 -1
  203. package/dist/components/table/use-fixed-columns.js.map +1 -1
  204. package/dist/components/table/use-rows.js.map +1 -1
  205. package/dist/components/table/use-table.js.map +1 -1
  206. package/dist/components/table-editor/table-editor.js.map +1 -1
  207. package/dist/components/tabs/style.js +1 -1
  208. package/dist/components/tabs/tabs-horizontal.js.map +1 -1
  209. package/dist/components/tabs/tabs-horizontal.vue.d.ts +3 -3
  210. package/dist/components/tabs/tabs-vertical.js.map +1 -1
  211. package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
  212. package/dist/components/tabs/tabs.js.map +1 -1
  213. package/dist/components/tabs/tabs.vue.d.ts +3 -3
  214. package/dist/components/tabs/use-tabs-bar.js.map +1 -1
  215. package/dist/components/tag/tag.js.map +1 -1
  216. package/dist/components/text/text.js.map +1 -1
  217. package/dist/components/textarea/style.js +1 -1
  218. package/dist/components/textarea/textarea.js.map +1 -1
  219. package/dist/components/textarea/textarea.vue.d.ts +3 -3
  220. package/dist/components/textarea/utils.js.map +1 -1
  221. package/dist/components/theme/schema.js.map +1 -1
  222. package/dist/components/theme/theme.js.map +1 -1
  223. package/dist/components/tip/tip.js.map +1 -1
  224. package/dist/components/tip/tip.vue.d.ts +1 -1
  225. package/dist/components/tip/use-nest.js.map +1 -1
  226. package/dist/components/tree/tree-node.js.map +1 -1
  227. package/dist/components/tree/tree-node2.js.map +1 -1
  228. package/dist/components/tree/tree.js.map +1 -1
  229. package/dist/components/tree/use-check.js.map +1 -1
  230. package/dist/components/tree/use-filter.js.map +1 -1
  231. package/dist/components/tree/use-select.js.map +1 -1
  232. package/dist/components/tree/use-tree-nodes.js.map +1 -1
  233. package/dist/components/tree-select/tree-select.js.map +1 -1
  234. package/dist/components/tree-select/tree-select.vue.d.ts +3 -3
  235. package/dist/components/watermark/watermark.js.map +1 -1
  236. package/dist/index.d.ts +4 -3
  237. package/dist/index.js +2 -1
  238. package/dist/install.js.map +1 -1
  239. package/dist/types/batch-edit.d.ts +2 -2
  240. package/dist/types/condition-editor.d.ts +21 -9
  241. package/dist/types/index.d.ts +2 -2
  242. package/package.json +13 -16
  243. package/src/components/action/style.scss +0 -6
  244. package/src/components/auto-complete/style.scss +0 -1
  245. package/src/components/auto-complete/style.ts +1 -1
  246. package/src/components/badge/badge.vue +1 -1
  247. package/src/components/batch-edit/style.ts +1 -1
  248. package/src/components/button/style.scss +1 -1
  249. package/src/components/cascade/use-select.ts +8 -6
  250. package/src/components/checkbox/style.ts +1 -1
  251. package/src/components/collapse/__test__/collapse.test.ts +3 -3
  252. package/src/components/condition-editor/components/condition-group.vue +118 -87
  253. package/src/components/condition-editor/components/condition-row.vue +137 -89
  254. package/src/components/condition-editor/condition-editor.vue +19 -48
  255. package/src/components/condition-editor/core/evaluator.ts +143 -57
  256. package/src/components/condition-editor/index.ts +6 -0
  257. package/src/components/condition-editor/style.scss +189 -102
  258. package/src/components/context-menu/style.ts +1 -1
  259. package/src/components/dialog/style.ts +2 -2
  260. package/src/components/drawer/style.ts +1 -1
  261. package/src/components/dropdown/style.ts +1 -1
  262. package/src/components/expression-editor/style.scss +1 -1
  263. package/src/components/form-item/form-item.vue +4 -9
  264. package/src/components/input/style.ts +1 -1
  265. package/src/components/loading/style.ts +1 -1
  266. package/src/components/menu/style.scss +1 -1
  267. package/src/components/message/style.scss +1 -1
  268. package/src/components/multi-select/style.ts +1 -1
  269. package/src/components/multi-tree-select/style.ts +1 -1
  270. package/src/components/number-input/__test__/number-input.test.ts +1 -1
  271. package/src/components/radio/style.ts +1 -1
  272. package/src/components/slider/slider.vue +1 -1
  273. package/src/components/table/di.ts +1 -1
  274. package/src/components/tabs/style.ts +1 -1
  275. package/src/components/textarea/style.ts +1 -1
  276. package/src/types/batch-edit.ts +2 -2
  277. package/src/types/condition-editor.ts +22 -8
@@ -1,66 +1,127 @@
1
+ import { o } from "@cat-kit/core";
1
2
  //#region src/components/condition-editor/core/evaluator.ts
2
- function resolveValue(item, data) {
3
- if (item.value.kind === "constant") return item.value.value;
4
- return String(getByPath(data, item.value.name) ?? "");
3
+ /**
4
+ * 求值表达式
5
+ *
6
+ * - 纯函数,不修改入参
7
+ * - 空表达式(无任何叶子节点)返回 `true`(视作"无限制")
8
+ * - 不完整的叶子(field/operator 缺失、或缺少所需值且 operator 需要值)按 `false` 计
9
+ * - 同组内 AND/OR 按 **从左到右、等优先级** 求值;需要更高优先级请用子分组
10
+ */
11
+ function evaluate(expression, options = {}) {
12
+ return evaluateGroup(expression, options);
5
13
  }
6
- function resolveCompareValue(item, data) {
7
- if (item.value.kind === "constant") return item.value.value;
8
- return String(getByPath(data, item.value.name) ?? "");
14
+ function evaluateGroup(group, options) {
15
+ const { children, connectors } = group;
16
+ if (children.length === 0) return true;
17
+ let acc = evaluateNode(children[0], options);
18
+ for (let i = 1; i < children.length; i++) {
19
+ const connector = connectors[i - 1] ?? "and";
20
+ const current = evaluateNode(children[i], options);
21
+ acc = connector === "and" ? acc && current : acc || current;
22
+ }
23
+ return acc;
9
24
  }
10
- function getByPath(obj, path) {
11
- return path.split(".").reduce((acc, key) => acc != null ? acc[key] : void 0, obj);
25
+ function evaluateNode(node, options) {
26
+ return node.type === "group" ? evaluateGroup(node, options) : evaluateLeaf(node, options);
12
27
  }
13
- function evaluateItem(item, data) {
14
- const resolved = resolveValue(item, data);
15
- const compareValue = resolveCompareValue(item, data);
16
- switch (item.operator) {
17
- case "empty": return resolved === "" || resolved === "undefined" || resolved === "null";
18
- case "not_empty": return resolved !== "" && resolved !== "undefined" && resolved !== "null";
19
- case "is_true": return resolved === "true" || resolved === "1";
20
- case "is_false": return resolved === "false" || resolved === "0" || resolved === "";
21
- case "eq": return resolved === compareValue;
22
- case "ne": return resolved !== compareValue;
23
- case "contains": return resolved.includes(compareValue);
24
- case "not_contains": return !resolved.includes(compareValue);
25
- case "gt": return Number(resolved) > Number(compareValue);
26
- case "lt": return Number(resolved) < Number(compareValue);
27
- case "gte": return Number(resolved) >= Number(compareValue);
28
- case "lte": return Number(resolved) <= Number(compareValue);
29
- case "before": return new Date(resolved).getTime() < new Date(compareValue).getTime();
30
- case "after": return new Date(resolved).getTime() > new Date(compareValue).getTime();
31
- case "in": return compareValue.split(",").map((s) => s.trim()).includes(resolved);
28
+ function evaluateLeaf(leaf, options) {
29
+ if (!leaf.field || !leaf.operator) return false;
30
+ const field = options.fields?.find((f) => f.value === leaf.field);
31
+ const left = readField(leaf.field, options.data);
32
+ const op = leaf.operator;
33
+ if (op === "empty") return isEmpty(left);
34
+ if (op === "not_empty") return !isEmpty(left);
35
+ if (op === "is_true") return toBool(left) === true;
36
+ if (op === "is_false") return toBool(left) === false;
37
+ if (!isValueProvided(leaf.value)) return false;
38
+ const right = resolveValue(leaf.value, options.data);
39
+ const fieldType = field?.type ?? "string";
40
+ switch (op) {
41
+ case "eq": return compareEq(left, right, fieldType);
42
+ case "ne": return !compareEq(left, right, fieldType);
43
+ case "contains": return toStr(left).includes(toStr(right));
44
+ case "not_contains": return !toStr(left).includes(toStr(right));
45
+ case "gt": return toNumber(left) > toNumber(right);
46
+ case "lt": return toNumber(left) < toNumber(right);
47
+ case "gte": return toNumber(left) >= toNumber(right);
48
+ case "lte": return toNumber(left) <= toNumber(right);
49
+ case "before": return toTime(left) < toTime(right);
50
+ case "after": return toTime(left) > toTime(right);
51
+ case "in": return (Array.isArray(right) ? right.map(toStr) : toStr(right).split(",").map((s) => s.trim()).filter(Boolean)).includes(toStr(left));
32
52
  default: return false;
33
53
  }
34
54
  }
35
- function evaluateGroup(group, data) {
36
- const conditionsResult = group.conditions.map((item) => {
37
- const result = evaluateItem(item, data);
38
- item._result = result;
39
- return result;
40
- });
41
- const groupsResult = group.groups.map((sub) => {
42
- const result = evaluateGroup(sub, data);
43
- sub._result = result;
44
- return result;
45
- });
46
- const allResults = [...conditionsResult, ...groupsResult];
47
- if (allResults.length === 0) return false;
48
- return group.logic === "and" ? allResults.every(Boolean) : allResults.some(Boolean);
55
+ function readField(path, data) {
56
+ if (!data) return void 0;
57
+ return o(data).get(path);
58
+ }
59
+ function resolveValue(value, data) {
60
+ if (value.kind === "constant") return value.value;
61
+ return readField(value.name, data);
62
+ }
63
+ function isValueProvided(value) {
64
+ if (value.kind === "constant") return value.value !== "";
65
+ return value.name !== "";
66
+ }
67
+ function isEmpty(v) {
68
+ if (v == null) return true;
69
+ if (typeof v === "string") return v.trim() === "";
70
+ if (Array.isArray(v)) return v.length === 0;
71
+ return false;
72
+ }
73
+ function toBool(v) {
74
+ if (typeof v === "boolean") return v;
75
+ if (typeof v === "number") return v !== 0;
76
+ if (typeof v === "string") {
77
+ const s = v.trim().toLowerCase();
78
+ if (s === "true" || s === "1") return true;
79
+ if (s === "false" || s === "0" || s === "") return false;
80
+ }
81
+ return Boolean(v);
49
82
  }
50
- function evaluate(expression, data) {
51
- const cloned = JSON.parse(JSON.stringify(expression));
52
- evaluateGroup(cloned, data);
53
- return cloned;
83
+ function toNumber(v) {
84
+ if (typeof v === "number") return v;
85
+ if (typeof v === "boolean") return v ? 1 : 0;
86
+ if (typeof v === "string") {
87
+ const n = Number(v);
88
+ return Number.isNaN(n) ? NaN : n;
89
+ }
90
+ return NaN;
91
+ }
92
+ function toTime(v) {
93
+ if (v instanceof Date) return v.getTime();
94
+ if (typeof v === "number") return v;
95
+ if (typeof v === "string" && v) return new Date(v).getTime();
96
+ return NaN;
97
+ }
98
+ function compareEq(left, right, type) {
99
+ if (type === "number") return toNumber(left) === toNumber(right);
100
+ if (type === "boolean") return toBool(left) === toBool(right);
101
+ if (type === "date") return toTime(left) === toTime(right);
102
+ return toStr(left) === toStr(right);
103
+ }
104
+ function toStr(v) {
105
+ if (v == null) return "";
106
+ if (typeof v === "string") return v;
107
+ if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") return String(v);
108
+ if (v instanceof Date) return v.toISOString();
109
+ try {
110
+ return JSON.stringify(v);
111
+ } catch {
112
+ return "";
113
+ }
54
114
  }
55
115
  function createEmptyGroup() {
56
116
  return {
57
- logic: "and",
58
- conditions: [],
59
- groups: []
117
+ type: "group",
118
+ children: [],
119
+ connectors: []
60
120
  };
61
121
  }
62
- function createEmptyItem() {
122
+ function createEmptyLeaf() {
63
123
  return {
124
+ type: "condition",
64
125
  field: "",
65
126
  operator: "eq",
66
127
  value: {
@@ -70,6 +131,6 @@ function createEmptyItem() {
70
131
  };
71
132
  }
72
133
  //#endregion
73
- export { createEmptyGroup, createEmptyItem, evaluate };
134
+ export { createEmptyGroup, createEmptyLeaf, evaluate };
74
135
 
75
136
  //# sourceMappingURL=evaluator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.js","names":[],"sources":["../../../../src/components/condition-editor/core/evaluator.ts"],"sourcesContent":["import type { ConditionExpression, ConditionGroup, ConditionItem } from '../../../types'\n\nfunction resolveValue(item: ConditionItem, data: Record<string, unknown>): string {\n if (item.value.kind === 'constant') return item.value.value\n return String(getByPath(data, item.value.name) ?? '')\n}\n\nfunction resolveCompareValue(item: ConditionItem, data: Record<string, unknown>): string {\n if (item.value.kind === 'constant') return item.value.value\n return String(getByPath(data, item.value.name) ?? '')\n}\n\nfunction getByPath(obj: Record<string, unknown>, path: string): unknown {\n return path.split('.').reduce((acc: any, key) => (acc != null ? acc[key] : undefined), obj)\n}\n\nfunction evaluateItem(item: ConditionItem, data: Record<string, unknown>): boolean {\n const resolved = resolveValue(item, data)\n const compareValue = resolveCompareValue(item, data)\n\n switch (item.operator) {\n case 'empty':\n return resolved === '' || resolved === 'undefined' || resolved === 'null'\n case 'not_empty':\n return resolved !== '' && resolved !== 'undefined' && resolved !== 'null'\n case 'is_true':\n return resolved === 'true' || resolved === '1'\n case 'is_false':\n return resolved === 'false' || resolved === '0' || resolved === ''\n case 'eq':\n return resolved === compareValue\n case 'ne':\n return resolved !== compareValue\n case 'contains':\n return resolved.includes(compareValue)\n case 'not_contains':\n return !resolved.includes(compareValue)\n case 'gt':\n return Number(resolved) > Number(compareValue)\n case 'lt':\n return Number(resolved) < Number(compareValue)\n case 'gte':\n return Number(resolved) >= Number(compareValue)\n case 'lte':\n return Number(resolved) <= Number(compareValue)\n case 'before':\n return new Date(resolved).getTime() < new Date(compareValue).getTime()\n case 'after':\n return new Date(resolved).getTime() > new Date(compareValue).getTime()\n case 'in': {\n const vals = compareValue.split(',').map((s) => s.trim())\n return vals.includes(resolved)\n }\n default:\n return false\n }\n}\n\nfunction evaluateGroup(group: ConditionGroup, data: Record<string, unknown>): boolean {\n const conditionsResult = group.conditions.map((item) => {\n const result = evaluateItem(item, data)\n item._result = result\n return result\n })\n\n const groupsResult = group.groups.map((sub) => {\n const result = evaluateGroup(sub, data)\n sub._result = result\n return result\n })\n\n const allResults = [...conditionsResult, ...groupsResult]\n if (allResults.length === 0) return false\n\n return group.logic === 'and' ? allResults.every(Boolean) : allResults.some(Boolean)\n}\n\nexport function evaluate(\n expression: ConditionExpression,\n data: Record<string, unknown>\n): ConditionExpression {\n const cloned = JSON.parse(JSON.stringify(expression)) as ConditionExpression\n evaluateGroup(cloned, data)\n return cloned\n}\n\nexport function createEmptyGroup(): ConditionGroup {\n return { logic: 'and', conditions: [], groups: [] }\n}\n\nexport function createEmptyItem(): ConditionItem {\n return { field: '', operator: 'eq', value: { kind: 'constant', value: '' } }\n}\n"],"mappings":";AAEA,SAAS,aAAa,MAAqB,MAAuC;AAChF,KAAI,KAAK,MAAM,SAAS,WAAY,QAAO,KAAK,MAAM;AACtD,QAAO,OAAO,UAAU,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG;;AAGvD,SAAS,oBAAoB,MAAqB,MAAuC;AACvF,KAAI,KAAK,MAAM,SAAS,WAAY,QAAO,KAAK,MAAM;AACtD,QAAO,OAAO,UAAU,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG;;AAGvD,SAAS,UAAU,KAA8B,MAAuB;AACtE,QAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,KAAU,QAAS,OAAO,OAAO,IAAI,OAAO,KAAA,GAAY,IAAI;;AAG7F,SAAS,aAAa,MAAqB,MAAwC;CACjF,MAAM,WAAW,aAAa,MAAM,KAAK;CACzC,MAAM,eAAe,oBAAoB,MAAM,KAAK;AAEpD,SAAQ,KAAK,UAAb;EACE,KAAK,QACH,QAAO,aAAa,MAAM,aAAa,eAAe,aAAa;EACrE,KAAK,YACH,QAAO,aAAa,MAAM,aAAa,eAAe,aAAa;EACrE,KAAK,UACH,QAAO,aAAa,UAAU,aAAa;EAC7C,KAAK,WACH,QAAO,aAAa,WAAW,aAAa,OAAO,aAAa;EAClE,KAAK,KACH,QAAO,aAAa;EACtB,KAAK,KACH,QAAO,aAAa;EACtB,KAAK,WACH,QAAO,SAAS,SAAS,aAAa;EACxC,KAAK,eACH,QAAO,CAAC,SAAS,SAAS,aAAa;EACzC,KAAK,KACH,QAAO,OAAO,SAAS,GAAG,OAAO,aAAa;EAChD,KAAK,KACH,QAAO,OAAO,SAAS,GAAG,OAAO,aAAa;EAChD,KAAK,MACH,QAAO,OAAO,SAAS,IAAI,OAAO,aAAa;EACjD,KAAK,MACH,QAAO,OAAO,SAAS,IAAI,OAAO,aAAa;EACjD,KAAK,SACH,QAAO,IAAI,KAAK,SAAS,CAAC,SAAS,GAAG,IAAI,KAAK,aAAa,CAAC,SAAS;EACxE,KAAK,QACH,QAAO,IAAI,KAAK,SAAS,CAAC,SAAS,GAAG,IAAI,KAAK,aAAa,CAAC,SAAS;EACxE,KAAK,KAEH,QADa,aAAa,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAC7C,CAAC,SAAS,SAAS;EAEhC,QACE,QAAO;;;AAIb,SAAS,cAAc,OAAuB,MAAwC;CACpF,MAAM,mBAAmB,MAAM,WAAW,KAAK,SAAS;EACtD,MAAM,SAAS,aAAa,MAAM,KAAK;AACvC,OAAK,UAAU;AACf,SAAO;GACP;CAEF,MAAM,eAAe,MAAM,OAAO,KAAK,QAAQ;EAC7C,MAAM,SAAS,cAAc,KAAK,KAAK;AACvC,MAAI,UAAU;AACd,SAAO;GACP;CAEF,MAAM,aAAa,CAAC,GAAG,kBAAkB,GAAG,aAAa;AACzD,KAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,QAAO,MAAM,UAAU,QAAQ,WAAW,MAAM,QAAQ,GAAG,WAAW,KAAK,QAAQ;;AAGrF,SAAgB,SACd,YACA,MACqB;CACrB,MAAM,SAAS,KAAK,MAAM,KAAK,UAAU,WAAW,CAAC;AACrD,eAAc,QAAQ,KAAK;AAC3B,QAAO;;AAGT,SAAgB,mBAAmC;AACjD,QAAO;EAAE,OAAO;EAAO,YAAY,EAAE;EAAE,QAAQ,EAAE;EAAE;;AAGrD,SAAgB,kBAAiC;AAC/C,QAAO;EAAE,OAAO;EAAI,UAAU;EAAM,OAAO;GAAE,MAAM;GAAY,OAAO;GAAI;EAAE"}
1
+ {"version":3,"file":"evaluator.js","names":[],"sources":["../../../../src/components/condition-editor/core/evaluator.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\n\nimport type {\n ConditionConnector,\n ConditionExpression,\n ConditionField,\n ConditionGroup,\n ConditionLeaf,\n ConditionNode,\n ConditionValue\n} from '../../../types'\n\nexport interface EvaluateOptions {\n /** 字段定义 —— 提供后按字段类型做类型感知比较 */\n fields?: ConditionField[]\n /** 上下文数据,用于解析 `kind: 'variable'` 引用 */\n data?: Record<string, unknown>\n}\n\n/**\n * 求值表达式\n *\n * - 纯函数,不修改入参\n * - 空表达式(无任何叶子节点)返回 `true`(视作\"无限制\")\n * - 不完整的叶子(field/operator 缺失、或缺少所需值且 operator 需要值)按 `false` 计\n * - 同组内 AND/OR 按 **从左到右、等优先级** 求值;需要更高优先级请用子分组\n */\nexport function evaluate(expression: ConditionExpression, options: EvaluateOptions = {}): boolean {\n return evaluateGroup(expression, options)\n}\n\nfunction evaluateGroup(group: ConditionGroup, options: EvaluateOptions): boolean {\n const { children, connectors } = group\n if (children.length === 0) return true\n\n let acc = evaluateNode(children[0]!, options)\n for (let i = 1; i < children.length; i++) {\n const connector: ConditionConnector = connectors[i - 1] ?? 'and'\n const current = evaluateNode(children[i]!, options)\n acc = connector === 'and' ? acc && current : acc || current\n }\n return acc\n}\n\nfunction evaluateNode(node: ConditionNode, options: EvaluateOptions): boolean {\n return node.type === 'group' ? evaluateGroup(node, options) : evaluateLeaf(node, options)\n}\n\nfunction evaluateLeaf(leaf: ConditionLeaf, options: EvaluateOptions): boolean {\n if (!leaf.field || !leaf.operator) return false\n const field = options.fields?.find((f) => f.value === leaf.field)\n const left = readField(leaf.field, options.data)\n const op = leaf.operator\n\n if (op === 'empty') return isEmpty(left)\n if (op === 'not_empty') return !isEmpty(left)\n if (op === 'is_true') return toBool(left) === true\n if (op === 'is_false') return toBool(left) === false\n\n // 其余 operator 需要一个右侧比较值\n if (!isValueProvided(leaf.value)) return false\n const right = resolveValue(leaf.value, options.data)\n\n const fieldType = field?.type ?? 'string'\n\n switch (op) {\n case 'eq':\n return compareEq(left, right, fieldType)\n case 'ne':\n return !compareEq(left, right, fieldType)\n case 'contains':\n return toStr(left).includes(toStr(right))\n case 'not_contains':\n return !toStr(left).includes(toStr(right))\n case 'gt':\n return toNumber(left) > toNumber(right)\n case 'lt':\n return toNumber(left) < toNumber(right)\n case 'gte':\n return toNumber(left) >= toNumber(right)\n case 'lte':\n return toNumber(left) <= toNumber(right)\n case 'before':\n return toTime(left) < toTime(right)\n case 'after':\n return toTime(left) > toTime(right)\n case 'in': {\n // 右侧可能是数组、逗号分隔字符串或单值\n const list = Array.isArray(right)\n ? right.map(toStr)\n : toStr(right)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n return list.includes(toStr(left))\n }\n default:\n return false\n }\n}\n\nfunction readField(path: string, data?: Record<string, unknown>): unknown {\n if (!data) return undefined\n return o(data).get(path)\n}\n\nfunction resolveValue(value: ConditionValue, data?: Record<string, unknown>): unknown {\n if (value.kind === 'constant') return value.value\n return readField(value.name, data)\n}\n\nfunction isValueProvided(value: ConditionValue): boolean {\n if (value.kind === 'constant') return value.value !== ''\n return value.name !== ''\n}\n\nfunction isEmpty(v: unknown): boolean {\n if (v == null) return true\n if (typeof v === 'string') return v.trim() === ''\n if (Array.isArray(v)) return v.length === 0\n return false\n}\n\nfunction toBool(v: unknown): boolean {\n if (typeof v === 'boolean') return v\n if (typeof v === 'number') return v !== 0\n if (typeof v === 'string') {\n const s = v.trim().toLowerCase()\n if (s === 'true' || s === '1') return true\n if (s === 'false' || s === '0' || s === '') return false\n }\n return Boolean(v)\n}\n\nfunction toNumber(v: unknown): number {\n if (typeof v === 'number') return v\n if (typeof v === 'boolean') return v ? 1 : 0\n if (typeof v === 'string') {\n const n = Number(v)\n return Number.isNaN(n) ? Number.NaN : n\n }\n return Number.NaN\n}\n\nfunction toTime(v: unknown): number {\n if (v instanceof Date) return v.getTime()\n if (typeof v === 'number') return v\n if (typeof v === 'string' && v) return new Date(v).getTime()\n return Number.NaN\n}\n\nfunction compareEq(left: unknown, right: unknown, type: ConditionField['type']): boolean {\n if (type === 'number') return toNumber(left) === toNumber(right)\n if (type === 'boolean') return toBool(left) === toBool(right)\n if (type === 'date') return toTime(left) === toTime(right)\n return toStr(left) === toStr(right)\n}\n\nfunction toStr(v: unknown): string {\n if (v == null) return ''\n if (typeof v === 'string') return v\n if (typeof v === 'number' || typeof v === 'boolean' || typeof v === 'bigint') return String(v)\n if (v instanceof Date) return v.toISOString()\n try {\n return JSON.stringify(v)\n } catch {\n return ''\n }\n}\n\n// ── 工厂 ─────────────────────────────────────────\n\nexport function createEmptyGroup(): ConditionGroup {\n return { type: 'group', children: [], connectors: [] }\n}\n\nexport function createEmptyLeaf(): ConditionLeaf {\n return { type: 'condition', field: '', operator: 'eq', value: { kind: 'constant', value: '' } }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"operators.js","names":[],"sources":["../../../../src/components/condition-editor/core/operators.ts"],"sourcesContent":["export interface OperatorDef {\n label: string\n value: string\n needValue: boolean\n}\n\nconst STRING_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含', value: 'contains', needValue: true },\n { label: '不包含', value: 'not_contains', needValue: true },\n { label: '为空', value: 'empty', needValue: false },\n { label: '不为空', value: 'not_empty', needValue: false }\n]\n\nconst NUMBER_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '大于', value: 'gt', needValue: true },\n { label: '小于', value: 'lt', needValue: true },\n { label: '大于等于', value: 'gte', needValue: true },\n { label: '小于等于', value: 'lte', needValue: true }\n]\n\nconst BOOLEAN_OPERATORS: OperatorDef[] = [\n { label: '是', value: 'is_true', needValue: false },\n { label: '否', value: 'is_false', needValue: false }\n]\n\nconst DATE_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '早于', value: 'before', needValue: true },\n { label: '晚于', value: 'after', needValue: true }\n]\n\nconst ENUM_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含于', value: 'in', needValue: true }\n]\n\nconst OPERATOR_MAP: Record<string, OperatorDef[]> = {\n string: STRING_OPERATORS,\n number: NUMBER_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n date: DATE_OPERATORS,\n enum: ENUM_OPERATORS\n}\n\nexport function getOperatorsByFieldType(type: string): OperatorDef[] {\n return OPERATOR_MAP[type] ?? STRING_OPERATORS\n}\n\nexport function getOperatorDef(type: string, operator: string): OperatorDef | undefined {\n return getOperatorsByFieldType(type).find((op) => op.value === operator)\n}\n"],"mappings":";AAMA,MAAM,mBAAkC;CACtC;EAAE,OAAO;EAAM,OAAO;EAAM,WAAW;EAAM;CAC7C;EAAE,OAAO;EAAO,OAAO;EAAM,WAAW;EAAM;CAC9C;EAAE,OAAO;EAAM,OAAO;EAAY,WAAW;EAAM;CACnD;EAAE,OAAO;EAAO,OAAO;EAAgB,WAAW;EAAM;CACxD;EAAE,OAAO;EAAM,OAAO;EAAS,WAAW;EAAO;CACjD;EAAE,OAAO;EAAO,OAAO;EAAa,WAAW;EAAO;CACvD;AA6BD,MAAM,eAA8C;CAClD,QAAQ;CACR,QAAQ;EA5BR;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAChD;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAuBxB;CACxB,SAAS,CApBT;EAAE,OAAO;EAAK,OAAO;EAAW,WAAW;EAAO,EAClD;EAAE,OAAO;EAAK,OAAO;EAAY,WAAW;EAAO,CAmBzB;CAC1B,MAAM;EAhBN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAU,WAAW;GAAM;EACjD;GAAE,OAAO;GAAM,OAAO;GAAS,WAAW;GAAM;EAa5B;CACpB,MAAM;EAVN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAQ1B;CACrB;AAED,SAAgB,wBAAwB,MAA6B;AACnE,QAAO,aAAa,SAAS"}
1
+ {"version":3,"file":"operators.js","names":[],"sources":["../../../../src/components/condition-editor/core/operators.ts"],"sourcesContent":["export interface OperatorDef {\n label: string\n value: string\n needValue: boolean\n}\n\nconst STRING_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含', value: 'contains', needValue: true },\n { label: '不包含', value: 'not_contains', needValue: true },\n { label: '为空', value: 'empty', needValue: false },\n { label: '不为空', value: 'not_empty', needValue: false }\n]\n\nconst NUMBER_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '大于', value: 'gt', needValue: true },\n { label: '小于', value: 'lt', needValue: true },\n { label: '大于等于', value: 'gte', needValue: true },\n { label: '小于等于', value: 'lte', needValue: true }\n]\n\nconst BOOLEAN_OPERATORS: OperatorDef[] = [\n { label: '是', value: 'is_true', needValue: false },\n { label: '否', value: 'is_false', needValue: false }\n]\n\nconst DATE_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '早于', value: 'before', needValue: true },\n { label: '晚于', value: 'after', needValue: true }\n]\n\nconst ENUM_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含于', value: 'in', needValue: true }\n]\n\nconst OPERATOR_MAP: Record<string, OperatorDef[]> = {\n string: STRING_OPERATORS,\n number: NUMBER_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n date: DATE_OPERATORS,\n enum: ENUM_OPERATORS\n}\n\nexport function getOperatorsByFieldType(type: string): OperatorDef[] {\n return OPERATOR_MAP[type] ?? STRING_OPERATORS\n}\n\nexport function getOperatorDef(type: string, operator: string): OperatorDef | undefined {\n return getOperatorsByFieldType(type).find((op) => op.value === operator)\n}\n"],"mappings":";AAMA,MAAM,mBAAkC;CACtC;EAAE,OAAO;EAAM,OAAO;EAAM,WAAW;EAAM;CAC7C;EAAE,OAAO;EAAO,OAAO;EAAM,WAAW;EAAM;CAC9C;EAAE,OAAO;EAAM,OAAO;EAAY,WAAW;EAAM;CACnD;EAAE,OAAO;EAAO,OAAO;EAAgB,WAAW;EAAM;CACxD;EAAE,OAAO;EAAM,OAAO;EAAS,WAAW;EAAO;CACjD;EAAE,OAAO;EAAO,OAAO;EAAa,WAAW;EAAO;CACvD;AA6BD,MAAM,eAA8C;CAClD,QAAQ;CACR,QAAQ;EA5BR;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAChD;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAuBxB;CACxB,SAAS,CApBT;EAAE,OAAO;EAAK,OAAO;EAAW,WAAW;EAAO,EAClD;EAAE,OAAO;EAAK,OAAO;EAAY,WAAW;EAAO,CAmBzB;CAC1B,MAAM;EAhBN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAU,WAAW;GAAM;EACjD;GAAE,OAAO;GAAM,OAAO;GAAS,WAAW;GAAM;EAa5B;CACpB,MAAM;EAVN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAQ1B;CACrB;AAED,SAAgB,wBAAwB,MAA6B;CACnE,OAAO,aAAa,SAAS"}
@@ -1 +1,2 @@
1
- import { _default } from "./condition-editor.vue.js";
1
+ import { _default } from "./condition-editor.vue.js";
2
+ import { EvaluateOptions, createEmptyGroup, createEmptyLeaf, evaluate } from "./core/evaluator.js";
@@ -15,125 +15,213 @@
15
15
  * --u-height-small: 24px;
16
16
  */
17
17
  /** 暗色:data-theme 与系统偏好,与 UITheme.injectBuiltInThemes 选择器策略一致 */
18
- .u-condition-editor__group-header {
18
+ .u-condition-editor {
19
+ font-size: 13px;
20
+ color: var(--u-text-color-main);
21
+ }
22
+ .u-condition-editor__group {
23
+ position: relative;
24
+ background-color: var(--u-bg-color-top);
25
+ border: 1px solid var(--u-border-muted-color);
26
+ border-radius: var(--u-radius-default);
27
+ padding: 12px;
28
+ }
29
+ .u-condition-editor__group--nested {
30
+ background-color: var(--u-bg-color-middle);
31
+ border-left: 3px solid var(--u-color-primary-light-7);
32
+ }
33
+ .u-condition-editor__group + .u-condition-editor__group {
34
+ margin-top: 8px;
35
+ }
36
+ .u-condition-editor__group-list {
37
+ list-style: none;
38
+ margin: 0;
39
+ padding: 0;
19
40
  display: flex;
20
- align-items: center;
41
+ flex-direction: column;
21
42
  gap: 6px;
22
- margin-bottom: 4px;
23
- }
24
- .u-condition-editor__group-body {
25
- border-left: 2px solid var(--u-border-muted-color);
26
- margin-left: 8px;
27
- padding-left: 10px;
28
43
  }
29
- .u-condition-editor__group-actions {
44
+ .u-condition-editor__group-item {
30
45
  display: flex;
31
- gap: 10px;
32
- padding: 2px 0;
46
+ align-items: flex-start;
47
+ gap: 8px;
33
48
  }
34
- .u-condition-editor__group-result {
35
- font-size: 11px;
36
- font-weight: 600;
49
+ .u-condition-editor__group-item-body {
50
+ flex: 1;
51
+ min-width: 0;
37
52
  }
38
- .u-condition-editor__group-result--pass {
39
- color: var(--u-color-success);
53
+ .u-condition-editor__group-empty {
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ padding: 8px;
58
+ color: var(--u-text-color-assist);
59
+ font-size: 12px;
40
60
  }
41
- .u-condition-editor__group-result--fail {
42
- color: var(--u-color-danger);
61
+ .u-condition-editor__group-empty-tip {
62
+ opacity: 0.7;
43
63
  }
44
- .u-condition-editor__logic-tag {
45
- display: inline-block;
46
- padding: 1px 8px;
64
+ .u-condition-editor__connector {
65
+ flex-shrink: 0;
66
+ width: 56px;
67
+ height: 28px;
68
+ display: inline-flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ margin-top: 2px;
47
72
  border-radius: var(--u-radius-small);
48
73
  font-size: 11px;
49
74
  font-weight: 600;
75
+ letter-spacing: 0.5px;
50
76
  cursor: pointer;
51
77
  user-select: none;
52
- transition: background-color 0.12s ease;
78
+ transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
53
79
  }
54
- .u-condition-editor__logic-tag--and {
55
- background-color: var(--u-color-primary-light-9);
80
+ .u-condition-editor__connector--and {
56
81
  color: var(--u-color-primary);
82
+ background-color: var(--u-color-primary-light-9);
57
83
  }
58
- .u-condition-editor__logic-tag--and:hover {
84
+ .u-condition-editor__connector--and:hover {
59
85
  background-color: var(--u-color-primary-light-8);
60
86
  }
61
- .u-condition-editor__logic-tag--or {
87
+ .u-condition-editor__connector--or {
88
+ color: var(--u-color-warning-dark-2);
62
89
  background-color: var(--u-color-warning-light-9);
63
- color: var(--u-color-warning);
64
90
  }
65
- .u-condition-editor__logic-tag--or:hover {
91
+ .u-condition-editor__connector--or:hover {
66
92
  background-color: var(--u-color-warning-light-8);
67
93
  }
68
- .u-condition-editor__row {
94
+ .u-condition-editor__connector:focus-visible {
95
+ outline: 2px solid var(--u-color-primary);
96
+ outline-offset: 1px;
97
+ }
98
+ .u-condition-editor__connector-placeholder {
99
+ flex-shrink: 0;
100
+ width: 56px;
101
+ height: 28px;
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ margin-top: 2px;
106
+ border-radius: var(--u-radius-small);
107
+ font-size: 11px;
108
+ font-weight: 600;
109
+ letter-spacing: 0.5px;
110
+ color: var(--u-text-color-assist);
111
+ background-color: transparent;
112
+ user-select: none;
113
+ }
114
+ .u-condition-editor__group-actions {
69
115
  display: flex;
116
+ flex-wrap: wrap;
70
117
  gap: 4px;
118
+ margin-top: 8px;
119
+ padding-left: calc(56px + 8px);
120
+ }
121
+ .u-condition-editor__action-btn {
122
+ display: inline-flex;
123
+ align-items: center;
124
+ gap: 4px;
125
+ height: 26px;
126
+ padding: 0 8px;
127
+ border: none;
128
+ border-radius: var(--u-radius-small);
129
+ background-color: transparent;
130
+ color: var(--u-color-primary);
131
+ font-size: 12px;
132
+ cursor: pointer;
133
+ transition: background-color 0.15s ease, color 0.15s ease;
134
+ }
135
+ .u-condition-editor__action-btn:hover {
136
+ background-color: var(--u-color-primary-light-9);
137
+ }
138
+ .u-condition-editor__action-btn:disabled {
139
+ cursor: not-allowed;
140
+ opacity: 0.5;
141
+ }
142
+ .u-condition-editor__action-btn--danger {
143
+ color: var(--u-color-danger);
144
+ }
145
+ .u-condition-editor__action-btn--danger:hover {
146
+ background-color: var(--u-color-danger-light-9);
147
+ }
148
+ .u-condition-editor__row {
149
+ display: flex;
150
+ gap: 6px;
71
151
  align-items: center;
72
- margin-bottom: 3px;
73
152
  }
74
153
  .u-condition-editor__field {
75
- width: 90px;
154
+ width: 140px;
76
155
  flex-shrink: 0;
77
156
  }
78
157
  .u-condition-editor__operator {
79
- width: 80px;
158
+ width: 110px;
80
159
  flex-shrink: 0;
81
160
  }
82
161
  .u-condition-editor__value {
83
162
  flex: 1;
84
- min-width: 0;
163
+ min-width: 120px;
85
164
  display: flex;
86
165
  align-items: center;
87
166
  }
88
167
  .u-condition-editor__value-input {
89
168
  width: 100%;
90
169
  height: 28px;
91
- padding: 0 8px;
170
+ padding: 0 10px;
92
171
  border: 1px solid var(--u-border-muted-color);
93
172
  border-radius: var(--u-radius-small);
94
- font-size: 12px;
173
+ font-size: 13px;
95
174
  color: var(--u-text-color-main);
96
175
  background-color: var(--u-bg-color-top);
97
176
  outline: none;
98
- transition: border-color 0.12s ease;
177
+ transition: border-color 0.15s ease;
99
178
  }
100
179
  .u-condition-editor__value-input::placeholder {
101
180
  color: var(--u-text-color-placeholder);
102
181
  }
182
+ .u-condition-editor__value-input:hover {
183
+ border-color: var(--u-color-primary-light-5);
184
+ }
103
185
  .u-condition-editor__value-input:focus {
104
186
  border-color: var(--u-color-primary);
105
187
  }
106
- .u-condition-editor__value-input:disabled {
188
+ .u-condition-editor__value-input:disabled, .u-condition-editor__value-input:read-only {
107
189
  background-color: var(--u-color-disabled);
108
190
  cursor: not-allowed;
109
191
  }
110
192
  .u-condition-editor__value-empty {
111
193
  font-size: 12px;
112
194
  color: var(--u-text-color-assist);
195
+ padding: 0 8px;
113
196
  }
114
197
  .u-condition-editor__value-chip {
115
198
  display: inline-flex;
116
199
  align-items: center;
117
200
  gap: 4px;
118
- padding: 0 8px;
119
- height: 22px;
201
+ max-width: 100%;
202
+ padding: 0 8px 0 10px;
203
+ height: 24px;
120
204
  font-size: 12px;
121
205
  color: var(--u-color-primary);
122
206
  background-color: var(--u-color-primary-light-9);
207
+ border: 1px solid var(--u-color-primary-light-7);
123
208
  border-radius: 999px;
124
209
  cursor: pointer;
125
210
  user-select: none;
126
- transition: background-color 0.12s ease, box-shadow 0.12s ease;
211
+ transition: background-color 0.15s ease, border-color 0.15s ease;
127
212
  }
128
213
  .u-condition-editor__value-chip:hover {
129
214
  background-color: var(--u-color-primary-light-8);
215
+ border-color: var(--u-color-primary-light-5);
130
216
  }
131
- .u-condition-editor__value-chip:hover .u-condition-editor__value-chip-close {
132
- opacity: 1;
133
- max-width: 14px;
134
- margin-left: 2px;
217
+ .u-condition-editor__value-chip:focus-visible {
218
+ outline: 2px solid var(--u-color-primary);
219
+ outline-offset: 1px;
135
220
  }
136
221
  .u-condition-editor__value-chip-label {
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ white-space: nowrap;
137
225
  pointer-events: none;
138
226
  }
139
227
  .u-condition-editor__value-chip-close {
@@ -141,63 +229,52 @@
141
229
  align-items: center;
142
230
  justify-content: center;
143
231
  width: 14px;
144
- max-width: 0;
145
- margin-left: 0;
146
- overflow: hidden;
147
- font-size: 14px;
232
+ height: 14px;
233
+ font-size: 10px;
148
234
  line-height: 1;
149
- color: var(--u-color-primary);
150
- opacity: 0;
151
- transition: opacity 0.12s ease, max-width 0.12s ease, margin-left 0.12s ease;
235
+ color: inherit;
236
+ opacity: 0.7;
237
+ border-radius: 50%;
238
+ transition: opacity 0.15s ease, background-color 0.15s ease;
152
239
  }
153
240
  .u-condition-editor__value-chip-close:hover {
154
- transform: scale(1.1);
241
+ opacity: 1;
242
+ background-color: var(--u-color-primary-light-7);
155
243
  }
156
244
  .u-condition-editor__row-delete {
157
245
  flex-shrink: 0;
158
- width: 16px;
159
- text-align: center;
160
- font-size: 15px;
246
+ width: 26px;
247
+ height: 26px;
248
+ display: inline-flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ border: none;
252
+ background-color: transparent;
161
253
  color: var(--u-text-color-assist);
254
+ border-radius: var(--u-radius-small);
162
255
  cursor: pointer;
163
- transition: color 0.12s ease;
256
+ font-size: 14px;
257
+ transition: color 0.15s ease, background-color 0.15s ease;
164
258
  }
165
259
  .u-condition-editor__row-delete:hover {
166
260
  color: var(--u-color-danger);
261
+ background-color: var(--u-color-danger-light-9);
167
262
  }
168
- .u-condition-editor__result {
169
- flex-shrink: 0;
170
- width: 16px;
171
- text-align: center;
172
- font-size: 11px;
173
- font-weight: 600;
174
- }
175
- .u-condition-editor__result--pass {
176
- color: var(--u-color-success);
177
- }
178
- .u-condition-editor__result--fail {
179
- color: var(--u-color-danger);
180
- }
181
- .u-condition-editor__result--none {
182
- color: var(--u-text-color-assist);
183
- }
184
- .u-condition-editor__add-btn {
185
- font-size: 11px;
186
- color: var(--u-color-primary);
187
- cursor: pointer;
188
- transition: color 0.12s ease;
189
- }
190
- .u-condition-editor__add-btn:hover {
191
- color: var(--u-color-primary-dark-2);
263
+ .u-condition-editor__row-delete:disabled {
264
+ cursor: not-allowed;
265
+ opacity: 0.4;
192
266
  }
193
267
  .u-condition-editor.is-disabled {
194
268
  cursor: not-allowed;
195
269
  }
196
- .u-condition-editor.is-disabled .u-condition-editor__logic-tag {
270
+ .u-condition-editor.is-disabled .u-condition-editor__connector {
197
271
  cursor: not-allowed;
198
272
  opacity: 0.6;
199
273
  }
200
- .u-condition-editor.is-disabled .u-condition-editor__add-btn {
274
+ .u-condition-editor.is-disabled .u-condition-editor__action-btn {
201
275
  cursor: not-allowed;
202
276
  opacity: 0.6;
203
277
  }
278
+ .u-condition-editor.is-readonly .u-condition-editor__connector {
279
+ cursor: default;
280
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","names":["MContextMenu"],"sources":["../../../src/components/context-menu/api.ts"],"sourcesContent":["import { createVNode, render, type VNode } from 'vue'\n\nimport type { ContextMenuProps } from '../../types'\nimport MContextMenu from './context-menu.vue'\n\nlet node: VNode\n\nexport const contextmenu = {\n pop(options: ContextMenuProps): void {\n if (node) {\n render(null, document.body)\n }\n\n node = createVNode(MContextMenu, {\n ...options,\n onDestroy() {\n render(null, document.body)\n }\n })\n\n render(node, document.body)\n }\n}\n"],"mappings":";;;AAKA,IAAI;AAEJ,MAAa,cAAc,EACzB,IAAI,SAAiC;AACnC,KAAI,KACF,QAAO,MAAM,SAAS,KAAK;AAG7B,QAAO,YAAYA,WAAc;EAC/B,GAAG;EACH,YAAY;AACV,UAAO,MAAM,SAAS,KAAK;;EAE9B,CAAC;AAEF,QAAO,MAAM,SAAS,KAAK;GAE9B"}
1
+ {"version":3,"file":"api.js","names":["MContextMenu"],"sources":["../../../src/components/context-menu/api.ts"],"sourcesContent":["import { createVNode, render, type VNode } from 'vue'\n\nimport type { ContextMenuProps } from '../../types'\nimport MContextMenu from './context-menu.vue'\n\nlet node: VNode\n\nexport const contextmenu = {\n pop(options: ContextMenuProps): void {\n if (node) {\n render(null, document.body)\n }\n\n node = createVNode(MContextMenu, {\n ...options,\n onDestroy() {\n render(null, document.body)\n }\n })\n\n render(node, document.body)\n }\n}\n"],"mappings":";;;AAKA,IAAI;AAEJ,MAAa,cAAc,EACzB,IAAI,SAAiC;CACnC,IAAI,MACF,OAAO,MAAM,SAAS,KAAK;CAG7B,OAAO,YAAYA,WAAc;EAC/B,GAAG;EACH,YAAY;GACV,OAAO,MAAM,SAAS,KAAK;;EAE9B,CAAC;CAEF,OAAO,MAAM,SAAS,KAAK;GAE9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu-item.js","names":[],"sources":["../../../src/components/context-menu/context-menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('disabled', disabled),\n bem.is('loading', loading),\n cls.em('item', 'menu')\n ]\"\n v-ripple=\"!disabled && !loading\"\n @click=\"handleClickMenu\"\n >\n <u-icon v-if=\"loading\" :class=\"bem.is('loading')\">\n <Loading />\n </u-icon>\n <template v-else>\n <u-icon v-if=\"menu.icon\">\n <component :is=\"menu.icon\" />\n </u-icon>\n <i v-else :class=\"cls.e('icon-place')\"></i>\n </template>\n\n <span :class=\"cls.e('label')\">{{ menu.label }}</span>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef } from 'vue'\n\nimport type { ContextMenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({\n name: 'ContextMenuItem'\n})\n\nconst { menu } = defineProps<{\n menu: ContextMenuItem\n}>()\n\nconst emit = defineEmits<{\n (e: 'click-start'): void\n (e: 'click-end'): void\n}>()\n\nconst { cls } = inject(ContextMenuDIKey)!\n\nconst loading = shallowRef(false)\n\nconst disabled = computed(() => {\n return (typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled) ?? false\n})\n\nfunction handleClickMenu() {\n if (disabled.value || loading.value) return\n emit('click-start')\n loading.value = true\n const result = menu.callback?.()\n\n if (result instanceof Promise) {\n return result\n .then(() => {})\n .finally(() => {\n emit('click-end')\n loading.value = false\n })\n }\n loading.value = false\n emit('click-end')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAKb,MAAM,EAAE,QAAQ,OAAO,iBAAiB;EAExC,MAAM,UAAU,WAAW,MAAK;EAEhC,MAAM,WAAW,eAAe;AAC9B,WAAQ,OAAO,QAAA,KAAK,aAAa,aAAa,QAAA,KAAK,UAAU,GAAG,QAAA,KAAK,aAAa;IACnF;EAED,SAAS,kBAAkB;AACzB,OAAI,SAAS,SAAS,QAAQ,MAAO;AACrC,QAAK,cAAa;AAClB,WAAQ,QAAQ;GAChB,MAAM,SAAS,QAAA,KAAK,YAAW;AAE/B,OAAI,kBAAkB,QACpB,QAAO,OACJ,WAAW,GAAE,CACb,cAAc;AACb,SAAK,YAAW;AAChB,YAAQ,QAAQ;KACjB;AAEL,WAAQ,QAAQ;AAChB,QAAK,YAAW;;;uCAtEhB,mBAqBK,MAAA;IApBF,OAAK,eAAA;KAAU,MAAA,IAAG,CAAC,EAAC,OAAA;KAAgB,MAAA,IAAG,CAAC,GAAE,YAAa,SAAA,MAAQ;KAAS,MAAA,IAAG,CAAC,GAAE,WAAY,QAAA,MAAO;KAAS,MAAA,IAAG,CAAC,GAAE,QAAA,OAAA;;IAOhH,SAAO;OAEM,QAAA,SAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;IAFe,OAAK,eAAE,MAAA,IAAG,CAAC,GAAE,UAAA,CAAA;;2BACxB,CAAX,YAAW,MAAA,QAAA,CAAA,CAAA,CAAA;;qCAEb,mBAKW,UAAA,EAAA,KAAA,GAAA,EAAA,CAJK,QAAA,KAAK,QAAA,WAAA,EAAnB,YAES,MAAA,YAAA,EAAA,EAAA,KAAA,GAAA,EAAA;2BADsB,EAAA,WAAA,EAA7B,YAA6B,wBAAb,QAAA,KAAK,KAAI,CAAA,EAAA,CAAA;;uBAE3B,mBAA2C,KAAA;;IAAhC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,aAAA,CAAA;wBAGzB,mBAAqD,QAAA,EAA9C,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA,EAAA,EAAA,gBAAc,QAAA,KAAK,MAAK,EAAA,EAAA,CAAA,EAAA,EAAA,GAAA,CAAA,CAAA,MAAA,QAAA,EAAA,CAbhC,SAAA,SAAQ,CAAK,QAAA,MAAO,CAAA,CAAA"}
1
+ {"version":3,"file":"context-menu-item.js","names":[],"sources":["../../../src/components/context-menu/context-menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('disabled', disabled),\n bem.is('loading', loading),\n cls.em('item', 'menu')\n ]\"\n v-ripple=\"!disabled && !loading\"\n @click=\"handleClickMenu\"\n >\n <u-icon v-if=\"loading\" :class=\"bem.is('loading')\">\n <Loading />\n </u-icon>\n <template v-else>\n <u-icon v-if=\"menu.icon\">\n <component :is=\"menu.icon\" />\n </u-icon>\n <i v-else :class=\"cls.e('icon-place')\"></i>\n </template>\n\n <span :class=\"cls.e('label')\">{{ menu.label }}</span>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef } from 'vue'\n\nimport type { ContextMenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({\n name: 'ContextMenuItem'\n})\n\nconst { menu } = defineProps<{\n menu: ContextMenuItem\n}>()\n\nconst emit = defineEmits<{\n (e: 'click-start'): void\n (e: 'click-end'): void\n}>()\n\nconst { cls } = inject(ContextMenuDIKey)!\n\nconst loading = shallowRef(false)\n\nconst disabled = computed(() => {\n return (typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled) ?? false\n})\n\nfunction handleClickMenu() {\n if (disabled.value || loading.value) return\n emit('click-start')\n loading.value = true\n const result = menu.callback?.()\n\n if (result instanceof Promise) {\n return result\n .then(() => {})\n .finally(() => {\n emit('click-end')\n loading.value = false\n })\n }\n loading.value = false\n emit('click-end')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAKb,MAAM,EAAE,QAAQ,OAAO,iBAAgB;EAEvC,MAAM,UAAU,WAAW,MAAK;EAEhC,MAAM,WAAW,eAAe;GAC9B,QAAQ,OAAO,QAAA,KAAK,aAAa,aAAa,QAAA,KAAK,UAAS,GAAI,QAAA,KAAK,aAAa;IACnF;EAED,SAAS,kBAAkB;GACzB,IAAI,SAAS,SAAS,QAAQ,OAAO;GACrC,KAAK,cAAa;GAClB,QAAQ,QAAQ;GAChB,MAAM,SAAS,QAAA,KAAK,YAAW;GAE/B,IAAI,kBAAkB,SACpB,OAAO,OACJ,WAAW,GAAE,CACb,cAAc;IACb,KAAK,YAAW;IAChB,QAAQ,QAAQ;KACjB;GAEL,QAAQ,QAAQ;GAChB,KAAK,YAAW;;;uCAtEhB,mBAqBK,MAAA;IApBF,OAAK,eAAA;KAAU,MAAA,IAAA,CAAI,EAAC,OAAA;KAAgB,MAAA,IAAA,CAAI,GAAE,YAAa,SAAA,MAAQ;KAAS,MAAA,IAAA,CAAI,GAAE,WAAY,QAAA,MAAO;KAAS,MAAA,IAAA,CAAI,GAAE,QAAA,OAAA;;IAOhH,SAAO;OAEM,QAAA,SAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;IAFe,OAAK,eAAE,MAAA,IAAA,CAAI,GAAE,UAAA,CAAA;;2BACxB,CAAX,YAAW,MAAA,QAAA,CAAA,CAAA,CAAA;;qCAEb,mBAKW,UAAA,EAAA,KAAA,GAAA,EAAA,CAJK,QAAA,KAAK,QAAA,WAAA,EAAnB,YAES,MAAA,YAAA,EAAA,EAAA,KAAA,GAAA,EAAA;2BADsB,EAAA,WAAA,EAA7B,YAA6B,wBAAb,QAAA,KAAK,KAAI,CAAA,EAAA,CAAA;;uBAE3B,mBAA2C,KAAA;;IAAhC,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,aAAA,CAAA;wBAGzB,mBAAqD,QAAA,EAA9C,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,QAAA,CAAA,EAAA,EAAA,gBAAc,QAAA,KAAK,MAAK,EAAA,EAAA,CAAA,EAAA,EAAA,GAAA,CAAA,CAAA,MAAA,QAAA,EAAA,CAbhC,SAAA,SAAQ,CAAK,QAAA,MAAO,CAAA,CAAA"}