dabke 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README.md +187 -0
  4. package/dist/client.d.ts +14 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +42 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/client.schemas.d.ts +250 -0
  9. package/dist/client.schemas.d.ts.map +1 -0
  10. package/dist/client.schemas.js +137 -0
  11. package/dist/client.schemas.js.map +1 -0
  12. package/dist/client.types.d.ts +34 -0
  13. package/dist/client.types.d.ts.map +1 -0
  14. package/dist/client.types.js +18 -0
  15. package/dist/client.types.js.map +1 -0
  16. package/dist/cpsat/model-builder.d.ts +128 -0
  17. package/dist/cpsat/model-builder.d.ts.map +1 -0
  18. package/dist/cpsat/model-builder.js +640 -0
  19. package/dist/cpsat/model-builder.js.map +1 -0
  20. package/dist/cpsat/response.d.ts +74 -0
  21. package/dist/cpsat/response.d.ts.map +1 -0
  22. package/dist/cpsat/response.js +92 -0
  23. package/dist/cpsat/response.js.map +1 -0
  24. package/dist/cpsat/rules/assign-together.d.ts +23 -0
  25. package/dist/cpsat/rules/assign-together.d.ts.map +1 -0
  26. package/dist/cpsat/rules/assign-together.js +78 -0
  27. package/dist/cpsat/rules/assign-together.js.map +1 -0
  28. package/dist/cpsat/rules/employee-assignment-priority.d.ts +64 -0
  29. package/dist/cpsat/rules/employee-assignment-priority.d.ts.map +1 -0
  30. package/dist/cpsat/rules/employee-assignment-priority.js +151 -0
  31. package/dist/cpsat/rules/employee-assignment-priority.js.map +1 -0
  32. package/dist/cpsat/rules/index.d.ts +13 -0
  33. package/dist/cpsat/rules/index.d.ts.map +1 -0
  34. package/dist/cpsat/rules/index.js +13 -0
  35. package/dist/cpsat/rules/index.js.map +1 -0
  36. package/dist/cpsat/rules/location-preference.d.ts +29 -0
  37. package/dist/cpsat/rules/location-preference.d.ts.map +1 -0
  38. package/dist/cpsat/rules/location-preference.js +59 -0
  39. package/dist/cpsat/rules/location-preference.js.map +1 -0
  40. package/dist/cpsat/rules/max-consecutive-days.d.ts +28 -0
  41. package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -0
  42. package/dist/cpsat/rules/max-consecutive-days.js +70 -0
  43. package/dist/cpsat/rules/max-consecutive-days.js.map +1 -0
  44. package/dist/cpsat/rules/max-hours-day.d.ts +57 -0
  45. package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -0
  46. package/dist/cpsat/rules/max-hours-day.js +159 -0
  47. package/dist/cpsat/rules/max-hours-day.js.map +1 -0
  48. package/dist/cpsat/rules/max-hours-week.d.ts +62 -0
  49. package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -0
  50. package/dist/cpsat/rules/max-hours-week.js +169 -0
  51. package/dist/cpsat/rules/max-hours-week.js.map +1 -0
  52. package/dist/cpsat/rules/max-shifts-day.d.ts +69 -0
  53. package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -0
  54. package/dist/cpsat/rules/max-shifts-day.js +170 -0
  55. package/dist/cpsat/rules/max-shifts-day.js.map +1 -0
  56. package/dist/cpsat/rules/min-consecutive-days.d.ts +29 -0
  57. package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -0
  58. package/dist/cpsat/rules/min-consecutive-days.js +104 -0
  59. package/dist/cpsat/rules/min-consecutive-days.js.map +1 -0
  60. package/dist/cpsat/rules/min-hours-day.d.ts +28 -0
  61. package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -0
  62. package/dist/cpsat/rules/min-hours-day.js +61 -0
  63. package/dist/cpsat/rules/min-hours-day.js.map +1 -0
  64. package/dist/cpsat/rules/min-hours-week.d.ts +29 -0
  65. package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -0
  66. package/dist/cpsat/rules/min-hours-week.js +68 -0
  67. package/dist/cpsat/rules/min-hours-week.js.map +1 -0
  68. package/dist/cpsat/rules/min-rest-between-shifts.d.ts +28 -0
  69. package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -0
  70. package/dist/cpsat/rules/min-rest-between-shifts.js +95 -0
  71. package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -0
  72. package/dist/cpsat/rules/registry.d.ts +7 -0
  73. package/dist/cpsat/rules/registry.d.ts.map +1 -0
  74. package/dist/cpsat/rules/registry.js +28 -0
  75. package/dist/cpsat/rules/registry.js.map +1 -0
  76. package/dist/cpsat/rules/resolver.d.ts +31 -0
  77. package/dist/cpsat/rules/resolver.d.ts.map +1 -0
  78. package/dist/cpsat/rules/resolver.js +124 -0
  79. package/dist/cpsat/rules/resolver.js.map +1 -0
  80. package/dist/cpsat/rules/rules.types.d.ts +32 -0
  81. package/dist/cpsat/rules/rules.types.d.ts.map +1 -0
  82. package/dist/cpsat/rules/rules.types.js +2 -0
  83. package/dist/cpsat/rules/rules.types.js.map +1 -0
  84. package/dist/cpsat/rules/scoping.d.ts +129 -0
  85. package/dist/cpsat/rules/scoping.d.ts.map +1 -0
  86. package/dist/cpsat/rules/scoping.js +190 -0
  87. package/dist/cpsat/rules/scoping.js.map +1 -0
  88. package/dist/cpsat/rules/time-off.d.ts +78 -0
  89. package/dist/cpsat/rules/time-off.d.ts.map +1 -0
  90. package/dist/cpsat/rules/time-off.js +261 -0
  91. package/dist/cpsat/rules/time-off.js.map +1 -0
  92. package/dist/cpsat/rules.d.ts +5 -0
  93. package/dist/cpsat/rules.d.ts.map +1 -0
  94. package/dist/cpsat/rules.js +4 -0
  95. package/dist/cpsat/rules.js.map +1 -0
  96. package/dist/cpsat/semantic-time.d.ts +198 -0
  97. package/dist/cpsat/semantic-time.d.ts.map +1 -0
  98. package/dist/cpsat/semantic-time.js +222 -0
  99. package/dist/cpsat/semantic-time.js.map +1 -0
  100. package/dist/cpsat/types.d.ts +180 -0
  101. package/dist/cpsat/types.d.ts.map +1 -0
  102. package/dist/cpsat/types.js +2 -0
  103. package/dist/cpsat/types.js.map +1 -0
  104. package/dist/cpsat/utils.d.ts +47 -0
  105. package/dist/cpsat/utils.d.ts.map +1 -0
  106. package/dist/cpsat/utils.js +92 -0
  107. package/dist/cpsat/utils.js.map +1 -0
  108. package/dist/cpsat/validation-reporter.d.ts +54 -0
  109. package/dist/cpsat/validation-reporter.d.ts.map +1 -0
  110. package/dist/cpsat/validation-reporter.js +261 -0
  111. package/dist/cpsat/validation-reporter.js.map +1 -0
  112. package/dist/cpsat/validation.types.d.ts +141 -0
  113. package/dist/cpsat/validation.types.d.ts.map +1 -0
  114. package/dist/cpsat/validation.types.js +14 -0
  115. package/dist/cpsat/validation.types.js.map +1 -0
  116. package/dist/datetime.utils.d.ts +245 -0
  117. package/dist/datetime.utils.d.ts.map +1 -0
  118. package/dist/datetime.utils.js +372 -0
  119. package/dist/datetime.utils.js.map +1 -0
  120. package/dist/errors.d.ts +12 -0
  121. package/dist/errors.d.ts.map +1 -0
  122. package/dist/errors.js +17 -0
  123. package/dist/errors.js.map +1 -0
  124. package/dist/index.d.ts +112 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +116 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/llms.d.ts +5 -0
  129. package/dist/llms.d.ts.map +1 -0
  130. package/dist/llms.js +8 -0
  131. package/dist/llms.js.map +1 -0
  132. package/dist/testing/index.d.ts +12 -0
  133. package/dist/testing/index.d.ts.map +1 -0
  134. package/dist/testing/index.js +11 -0
  135. package/dist/testing/index.js.map +1 -0
  136. package/dist/testing/solver-container.d.ts +49 -0
  137. package/dist/testing/solver-container.d.ts.map +1 -0
  138. package/dist/testing/solver-container.js +127 -0
  139. package/dist/testing/solver-container.js.map +1 -0
  140. package/dist/types.d.ts +155 -0
  141. package/dist/types.d.ts.map +1 -0
  142. package/dist/types.js +20 -0
  143. package/dist/types.js.map +1 -0
  144. package/dist/validation.d.ts +105 -0
  145. package/dist/validation.d.ts.map +1 -0
  146. package/dist/validation.js +130 -0
  147. package/dist/validation.js.map +1 -0
  148. package/llms.txt +2188 -0
  149. package/package.json +76 -0
  150. package/solver/Dockerfile +31 -0
  151. package/solver/README.md +23 -0
  152. package/solver/pyproject.toml +28 -0
  153. package/solver/src/solver/__init__.py +1 -0
  154. package/solver/src/solver/app.py +24 -0
  155. package/solver/src/solver/models.py +120 -0
  156. package/solver/src/solver/solver.py +359 -0
  157. package/solver/tests/test_solver.py +156 -0
  158. package/solver/uv.lock +661 -0
  159. package/src/client.schemas.ts +163 -0
  160. package/src/client.ts +67 -0
  161. package/src/client.types.ts +66 -0
  162. package/src/cpsat/model-builder.ts +858 -0
  163. package/src/cpsat/response.ts +130 -0
  164. package/src/cpsat/rules/assign-together.ts +96 -0
  165. package/src/cpsat/rules/employee-assignment-priority.ts +182 -0
  166. package/src/cpsat/rules/index.ts +12 -0
  167. package/src/cpsat/rules/location-preference.ts +68 -0
  168. package/src/cpsat/rules/max-consecutive-days.ts +98 -0
  169. package/src/cpsat/rules/max-hours-day.ts +187 -0
  170. package/src/cpsat/rules/max-hours-week.ts +197 -0
  171. package/src/cpsat/rules/max-shifts-day.ts +198 -0
  172. package/src/cpsat/rules/min-consecutive-days.ts +140 -0
  173. package/src/cpsat/rules/min-hours-day.ts +69 -0
  174. package/src/cpsat/rules/min-hours-week.ts +77 -0
  175. package/src/cpsat/rules/min-rest-between-shifts.ts +121 -0
  176. package/src/cpsat/rules/registry.ts +49 -0
  177. package/src/cpsat/rules/resolver.ts +181 -0
  178. package/src/cpsat/rules/rules.types.ts +41 -0
  179. package/src/cpsat/rules/scoping.ts +340 -0
  180. package/src/cpsat/rules/time-off.ts +336 -0
  181. package/src/cpsat/rules.ts +27 -0
  182. package/src/cpsat/semantic-time.ts +463 -0
  183. package/src/cpsat/types.ts +194 -0
  184. package/src/cpsat/utils.ts +105 -0
  185. package/src/cpsat/validation-reporter.ts +366 -0
  186. package/src/cpsat/validation.types.ts +185 -0
  187. package/src/datetime.utils.ts +426 -0
  188. package/src/errors.ts +17 -0
  189. package/src/index.ts +289 -0
  190. package/src/llms.ts +9 -0
  191. package/src/testing/index.ts +12 -0
  192. package/src/testing/solver-container.ts +172 -0
  193. package/src/types.ts +191 -0
  194. package/src/validation.ts +188 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ This changelog was generated from the git history of the project when it was
6
+ named `scheduling-core`, prior to the rename to `dabke` in v0.78.0.
7
+
8
+ ## 0.78.0 (2026-02-07)
9
+
10
+ - Rename package from `scheduling-core` to `dabke`
11
+
12
+ ## 0.77.0 (2026-02-02)
13
+
14
+ ### Breaking Changes
15
+
16
+ - Replace singular `roleId` with `roleIds` array in coverage requirements
17
+ - Enforce `roleIds`/`skillIds` requirement at compile time with discriminated union types
18
+
19
+ ## 0.76.0 (2026-02-01)
20
+
21
+ - Add validation grouping with `groupKey` for meaningful summary reports
22
+ - Add `summarizeValidation()` to aggregate validation items by source instruction
23
+
24
+ ## 0.75.0 (2026-01-29)
25
+
26
+ - Add fair distribution of shifts across team members (`fairDistribution` option)
27
+ - Track mandatory coverage constraints as passed validation items
28
+
29
+ ## 0.74.0 (2026-01-27)
30
+
31
+ - Add `SchedulingPeriod` type for date range with day-of-week filtering
32
+ - Enforce minimum 2 members in `assign-together` rule at the type level
33
+
34
+ ## 0.73.0 (2026-01-25)
35
+
36
+ - Add schedule violation diagnostics with detailed error reporting
37
+ - Add stable deterministic IDs to validation items
38
+ - Fix: preserve scope when IDs don't match during rule resolution
39
+
40
+ ## 0.72.0 (2026-01-13)
41
+
42
+ ### Breaking Changes
43
+
44
+ - Drop legacy solver and related rules API — CP-SAT is now the only solver path
45
+
46
+ ### Features
47
+
48
+ - Add skill-based coverage requirements (`skillIds` on coverage)
49
+ - Add interval variables, `NoOverlap` constraints, and bucketed coverage
50
+ - Better role mapping strategy for multi-role team members
51
+ - Inherit `weekStartsOn` from `ModelBuilder` in weekly rules
52
+
53
+ ## 0.71.0 (2026-01-11)
54
+
55
+ - Fix coverage constraints to use time-indexed approach for accuracy
56
+ - Make time horizon end date inclusive
57
+ - Handle mandatory coverage priority correctly
58
+ - Make role IDs optional on shift patterns (support role-agnostic shifts)
59
+ - Support multiple role ID restrictions on `ShiftPattern`
60
+ - Improve `ShiftPattern` type documentation and enforce non-empty `roleIds`
61
+
62
+ ## 0.70.0 (2026-01-10)
63
+
64
+ ### Features
65
+
66
+ - Add CP-SAT compilation path via `ModelBuilder`
67
+ - Add semantic time definitions (`defineSemanticTimes`) with day-specific variants
68
+ - Type-safe coverage requirements using semantic time names
69
+
70
+ ## 0.69.0 (2026-01-09)
71
+
72
+ - Initial setup for custom CP-SAT solver integration (replacing hosted OR-Tools)
73
+
74
+ ## 0.68.0 (2026-01-07)
75
+
76
+ - Add comprehensive tests and API documentation
77
+
78
+ ## 0.67.0 (2025-11-23)
79
+
80
+ - Improved rules system with better priority handling
81
+ - Better prompt injection for LLM code generation
82
+ - Time scope resolution for rules (date ranges, days of week, recurring periods)
83
+ - Refactored coverage requirements
84
+
85
+ ## 0.66.0 (2025-11-05)
86
+
87
+ - Refactor to visitor pattern for rule compilation
88
+ - Improve LLM performance with better API documentation
89
+
90
+ ## 0.65.0 (2025-10-21)
91
+
92
+ - Add rules: `max-hours-week`, `min-hours-week`, `max-consecutive-days`,
93
+ `min-consecutive-days`, `min-rest-between-shifts`, `assign-together`
94
+
95
+ ## 0.64.0 (2025-10-13)
96
+
97
+ - Refactor date period splitting as shared utility
98
+ - Fix dependency issues
99
+
100
+ ## 0.63.0 (2025-09-26)
101
+
102
+ - Add `min-hours-day` rule
103
+ - Make rule factory type-safe with `CpsatRuleRegistry`
104
+
105
+ ## 0.62.0 (2025-09-18)
106
+
107
+ - Add auto-generated `llms.txt` API reference
108
+ - Complete migration to modular architecture
109
+
110
+ ## 0.61.0 (2025-09-01)
111
+
112
+ - Rename "time window" concept to "named period"
113
+
114
+ ## 0.60.0 (2025-08-28)
115
+
116
+ - Initial release as `scheduling-core`
117
+ - `ModelBuilder` for building constraint programming models
118
+ - Built-in rules: `max-hours-day`, `max-shifts-day`, `time-off`, `employee-assignment-priority`, `location-preference`
119
+ - `HttpSolverClient` for solver communication
120
+ - Type-safe configuration with TypeScript
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Christian Klotz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # dabke
2
+
3
+ Scheduling library powered by constraint programming (CP-SAT).
4
+
5
+ Define your team, shifts, coverage, and rules — dabke turns them into an optimized schedule.
6
+
7
+ ## Features
8
+
9
+ - **Declarative scheduling** — describe what you need, not how to solve it
10
+ - **Built-in rules** — max hours, time off, rest periods, consecutive days, and more
11
+ - **Semantic time** — define named time periods ("lunch", "closing") that resolve per day
12
+ - **Soft & hard constraints** — priorities from `LOW` (preference) to `MANDATORY` (hard constraint)
13
+ - **Scoped rules** — apply rules globally, per person, per role, or per skill
14
+ - **Validation** — detailed error reporting with coverage gaps and rule violations
15
+ - **LLM-friendly** — ships `llms.txt` with full API docs for AI code generation
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install dabke
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import {
27
+ ModelBuilder,
28
+ HttpSolverClient,
29
+ parseSolverResponse,
30
+ resolveAssignments,
31
+ } from "dabke";
32
+
33
+ // Define team
34
+ const employees = [
35
+ { id: "alice", roleIds: ["server"] },
36
+ { id: "bob", roleIds: ["server"] },
37
+ { id: "charlie", roleIds: ["chef"] },
38
+ ];
39
+
40
+ // Define shift patterns
41
+ const shiftPatterns = [
42
+ { id: "morning", startTime: { hours: 8 }, endTime: { hours: 16 } },
43
+ { id: "evening", startTime: { hours: 16 }, endTime: { hours: 23 } },
44
+ ];
45
+
46
+ // Define coverage requirements
47
+ const coverage = [
48
+ {
49
+ day: "2026-02-09",
50
+ startTime: { hours: 8 },
51
+ endTime: { hours: 16 },
52
+ roleIds: ["server"],
53
+ targetCount: 1,
54
+ priority: "MANDATORY" as const,
55
+ },
56
+ {
57
+ day: "2026-02-09",
58
+ startTime: { hours: 16 },
59
+ endTime: { hours: 23 },
60
+ roleIds: ["server"],
61
+ targetCount: 1,
62
+ priority: "MANDATORY" as const,
63
+ },
64
+ ];
65
+
66
+ // Build the model
67
+ const builder = new ModelBuilder({
68
+ employees,
69
+ shiftPatterns,
70
+ coverage,
71
+ schedulingPeriod: {
72
+ specificDates: ["2026-02-09"],
73
+ },
74
+ ruleConfigs: [
75
+ { name: "max-hours-day", config: { hours: 8, priority: "MANDATORY" } },
76
+ { name: "min-rest-between-shifts", config: { hours: 10, priority: "MANDATORY" } },
77
+ ],
78
+ });
79
+
80
+ const { request } = builder.compile();
81
+
82
+ // Solve (requires a CP-SAT solver endpoint)
83
+ const solver = new HttpSolverClient(fetch, "https://your-solver-endpoint");
84
+ const response = await solver.solve(request);
85
+ const result = parseSolverResponse(response);
86
+
87
+ if (result.status === "OPTIMAL" || result.status === "FEASIBLE") {
88
+ const shifts = resolveAssignments(result.assignments, shiftPatterns);
89
+ for (const shift of shifts) {
90
+ console.log(
91
+ `${shift.employeeId}: ${shift.day} ${shift.startTime.hours}:00–${shift.endTime.hours}:00`
92
+ );
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Semantic Time
98
+
99
+ Define named time periods that can vary by day, then write coverage requirements in business terms:
100
+
101
+ ```typescript
102
+ import { defineSemanticTimes } from "dabke";
103
+
104
+ const times = defineSemanticTimes({
105
+ lunch: [
106
+ { startTime: { hours: 11, minutes: 30 }, endTime: { hours: 14 }, days: ["monday", "tuesday", "wednesday", "thursday", "friday"] },
107
+ { startTime: { hours: 12 }, endTime: { hours: 15 }, days: ["saturday", "sunday"] },
108
+ ],
109
+ closing: { startTime: { hours: 21 }, endTime: { hours: 23 } },
110
+ });
111
+
112
+ const coverage = times.coverage([
113
+ { semanticTime: "lunch", roleIds: ["server"], targetCount: 3, priority: "MANDATORY" },
114
+ { semanticTime: "closing", roleIds: ["server"], targetCount: 1, priority: "HIGH" },
115
+ ]);
116
+ ```
117
+
118
+ ## Built-in Rules
119
+
120
+ | Rule | Description |
121
+ |------|-------------|
122
+ | `max-hours-day` | Max hours per person per day |
123
+ | `max-hours-week` | Max hours per person per week |
124
+ | `min-hours-day` | Min hours per person per day |
125
+ | `min-hours-week` | Min hours per person per week |
126
+ | `max-shifts-day` | Max shift assignments per day |
127
+ | `max-consecutive-days` | Max consecutive working days |
128
+ | `min-consecutive-days` | Min consecutive working days |
129
+ | `min-rest-between-shifts` | Min rest hours between shifts |
130
+ | `time-off` | Block assignments during periods |
131
+ | `employee-assignment-priority` | Prefer or avoid assigning team members |
132
+ | `assign-together` | Keep team members on the same shifts |
133
+ | `location-preference` | Prefer team members at specific locations |
134
+
135
+ All rules support scoping by person, role, skill, and time period (date ranges, days of week, recurring periods).
136
+
137
+ ## Validation
138
+
139
+ dabke validates schedules and reports coverage gaps and rule violations:
140
+
141
+ ```typescript
142
+ import { ValidationReporterImpl, summarizeValidation } from "dabke";
143
+
144
+ const reporter = new ValidationReporterImpl();
145
+ const builder = new ModelBuilder({ ...config, reporter });
146
+ const { request, validation, canSolve } = builder.compile();
147
+
148
+ // Pre-solve validation
149
+ if (!canSolve) {
150
+ for (const error of validation.errors) {
151
+ console.error(error.reason);
152
+ }
153
+ }
154
+
155
+ // Post-solve validation (after solving)
156
+ reporter.analyzeSolution(response);
157
+ const results = reporter.getValidation();
158
+ const summaries = summarizeValidation(results);
159
+
160
+ for (const s of summaries) {
161
+ console.log(`${s.description}: ${s.status} (${s.passedCount}/${s.passedCount + s.violatedCount})`);
162
+ }
163
+ ```
164
+
165
+ ## LLM Integration
166
+
167
+ dabke ships an `llms.txt` file with complete API documentation, designed for AI code generation:
168
+
169
+ ```typescript
170
+ import { apiDocs } from "dabke/llms";
171
+
172
+ // Pass to your LLM as context for generating scheduling code
173
+ ```
174
+
175
+ Or read the file directly:
176
+
177
+ ```bash
178
+ cat node_modules/dabke/llms.txt
179
+ ```
180
+
181
+ ## Solver
182
+
183
+ dabke compiles scheduling problems into a JSON-based constraint model. You need a CP-SAT solver service to solve it. The model format is compatible with Google OR-Tools CP-SAT solver.
184
+
185
+ ## License
186
+
187
+ [MIT](LICENSE)
@@ -0,0 +1,14 @@
1
+ import { type FetcherLike, type SolverClient, type SolverRequest, type SolverResponse } from "./client.types.js";
2
+ export type { SolverClient, SolverRequest, SolverResponse, SolverVariable, SolverConstraint, SolverTerm, SolverObjective, FetcherLike, } from "./client.types.js";
3
+ /**
4
+ * Generic HTTP client for the solver service.
5
+ */
6
+ export declare class HttpSolverClient implements SolverClient {
7
+ #private;
8
+ constructor(fetcher: FetcherLike, baseUrl?: string);
9
+ solve(request: SolverRequest, options?: {
10
+ signal?: AbortSignal;
11
+ }): Promise<SolverResponse>;
12
+ health(): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAS3B;;GAEG;AACH,qBAAa,gBAAiB,YAAW,YAAY;;gBAIvC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,MAAgC;IAKrE,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAqB1F,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ9B"}
package/dist/client.js ADDED
@@ -0,0 +1,42 @@
1
+ const normalizeFetch = (fetcher) => {
2
+ if (typeof fetcher === "function")
3
+ return fetcher;
4
+ return fetcher.fetch.bind(fetcher);
5
+ };
6
+ /**
7
+ * Generic HTTP client for the solver service.
8
+ */
9
+ export class HttpSolverClient {
10
+ #fetch;
11
+ #baseUrl;
12
+ constructor(fetcher, baseUrl = "http://localhost:8080") {
13
+ this.#fetch = normalizeFetch(fetcher);
14
+ this.#baseUrl = baseUrl.replace(/\/$/, "");
15
+ }
16
+ async solve(request, options) {
17
+ const res = await this.#fetch(`${this.#baseUrl}/solve`, {
18
+ method: "POST",
19
+ headers: { "Content-Type": "application/json" },
20
+ body: JSON.stringify(request),
21
+ signal: options?.signal,
22
+ });
23
+ const bodyText = await res.text();
24
+ if (!res.ok) {
25
+ const detail = bodyText ? `: ${bodyText}` : "";
26
+ throw new Error(`Solver returned ${res.status}${detail}`);
27
+ }
28
+ if (!bodyText) {
29
+ throw new Error("Solver returned an empty response");
30
+ }
31
+ return JSON.parse(bodyText);
32
+ }
33
+ async health() {
34
+ const res = await this.#fetch(`${this.#baseUrl}/health`);
35
+ if (!res.ok) {
36
+ const detail = await res.text().catch(() => "");
37
+ const suffix = detail ? `: ${detail}` : "";
38
+ throw new Error(`Solver health check failed with ${res.status}${suffix}`);
39
+ }
40
+ }
41
+ }
42
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAkBA,MAAM,cAAc,GAAG,CACrB,OAAoB,EAC8C,EAAE;IACpE,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC;IAClD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAiE;IACvE,QAAQ,CAAS;IAEjB,YAAY,OAAoB,EAAE,UAAkB,uBAAuB;QACzE,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAsB,EAAE,OAAkC;QACpE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,QAAQ,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAmB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,SAAS,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Zod schemas for CP-SAT solver transport types.
3
+ *
4
+ * These schemas define the contract between scheduling clients and the solver service.
5
+ * TypeScript types are derived from these schemas using z.infer to ensure they stay in sync.
6
+ *
7
+ * @see client.types.ts for the derived TypeScript types
8
+ */
9
+ import { z } from "zod";
10
+ export declare const SolverTermSchema: z.ZodObject<{
11
+ var: z.ZodString;
12
+ coeff: z.ZodNumber;
13
+ }, z.core.$strip>;
14
+ export declare const BoolVariableSchema: z.ZodObject<{
15
+ type: z.ZodLiteral<"bool">;
16
+ name: z.ZodString;
17
+ }, z.core.$strip>;
18
+ export declare const IntVariableSchema: z.ZodObject<{
19
+ type: z.ZodLiteral<"int">;
20
+ name: z.ZodString;
21
+ min: z.ZodNumber;
22
+ max: z.ZodNumber;
23
+ }, z.core.$strip>;
24
+ export declare const IntervalVariableSchema: z.ZodObject<{
25
+ type: z.ZodLiteral<"interval">;
26
+ name: z.ZodString;
27
+ start: z.ZodNumber;
28
+ end: z.ZodNumber;
29
+ size: z.ZodNumber;
30
+ presenceVar: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strip>;
32
+ export declare const SolverVariableSchema: z.ZodUnion<readonly [z.ZodObject<{
33
+ type: z.ZodLiteral<"bool">;
34
+ name: z.ZodString;
35
+ }, z.core.$strip>, z.ZodObject<{
36
+ type: z.ZodLiteral<"int">;
37
+ name: z.ZodString;
38
+ min: z.ZodNumber;
39
+ max: z.ZodNumber;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ type: z.ZodLiteral<"interval">;
42
+ name: z.ZodString;
43
+ start: z.ZodNumber;
44
+ end: z.ZodNumber;
45
+ size: z.ZodNumber;
46
+ presenceVar: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>]>;
48
+ export declare const LinearConstraintSchema: z.ZodObject<{
49
+ type: z.ZodLiteral<"linear">;
50
+ terms: z.ZodArray<z.ZodObject<{
51
+ var: z.ZodString;
52
+ coeff: z.ZodNumber;
53
+ }, z.core.$strip>>;
54
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">, z.ZodLiteral<"==">]>;
55
+ rhs: z.ZodNumber;
56
+ }, z.core.$strip>;
57
+ export declare const SoftLinearConstraintSchema: z.ZodObject<{
58
+ type: z.ZodLiteral<"soft_linear">;
59
+ terms: z.ZodArray<z.ZodObject<{
60
+ var: z.ZodString;
61
+ coeff: z.ZodNumber;
62
+ }, z.core.$strip>>;
63
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">]>;
64
+ rhs: z.ZodNumber;
65
+ penalty: z.ZodNumber;
66
+ id: z.ZodOptional<z.ZodString>;
67
+ }, z.core.$strip>;
68
+ export declare const ExactlyOneConstraintSchema: z.ZodObject<{
69
+ type: z.ZodLiteral<"exactly_one">;
70
+ vars: z.ZodArray<z.ZodString>;
71
+ }, z.core.$strip>;
72
+ export declare const AtMostOneConstraintSchema: z.ZodObject<{
73
+ type: z.ZodLiteral<"at_most_one">;
74
+ vars: z.ZodArray<z.ZodString>;
75
+ }, z.core.$strip>;
76
+ export declare const ImplicationConstraintSchema: z.ZodObject<{
77
+ type: z.ZodLiteral<"implication">;
78
+ if: z.ZodString;
79
+ then: z.ZodString;
80
+ }, z.core.$strip>;
81
+ export declare const BoolOrConstraintSchema: z.ZodObject<{
82
+ type: z.ZodLiteral<"bool_or">;
83
+ vars: z.ZodArray<z.ZodString>;
84
+ }, z.core.$strip>;
85
+ export declare const BoolAndConstraintSchema: z.ZodObject<{
86
+ type: z.ZodLiteral<"bool_and">;
87
+ vars: z.ZodArray<z.ZodString>;
88
+ }, z.core.$strip>;
89
+ export declare const NoOverlapConstraintSchema: z.ZodObject<{
90
+ type: z.ZodLiteral<"no_overlap">;
91
+ intervals: z.ZodArray<z.ZodString>;
92
+ }, z.core.$strip>;
93
+ export declare const SolverConstraintSchema: z.ZodUnion<readonly [z.ZodObject<{
94
+ type: z.ZodLiteral<"linear">;
95
+ terms: z.ZodArray<z.ZodObject<{
96
+ var: z.ZodString;
97
+ coeff: z.ZodNumber;
98
+ }, z.core.$strip>>;
99
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">, z.ZodLiteral<"==">]>;
100
+ rhs: z.ZodNumber;
101
+ }, z.core.$strip>, z.ZodObject<{
102
+ type: z.ZodLiteral<"soft_linear">;
103
+ terms: z.ZodArray<z.ZodObject<{
104
+ var: z.ZodString;
105
+ coeff: z.ZodNumber;
106
+ }, z.core.$strip>>;
107
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">]>;
108
+ rhs: z.ZodNumber;
109
+ penalty: z.ZodNumber;
110
+ id: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>, z.ZodObject<{
112
+ type: z.ZodLiteral<"exactly_one">;
113
+ vars: z.ZodArray<z.ZodString>;
114
+ }, z.core.$strip>, z.ZodObject<{
115
+ type: z.ZodLiteral<"at_most_one">;
116
+ vars: z.ZodArray<z.ZodString>;
117
+ }, z.core.$strip>, z.ZodObject<{
118
+ type: z.ZodLiteral<"implication">;
119
+ if: z.ZodString;
120
+ then: z.ZodString;
121
+ }, z.core.$strip>, z.ZodObject<{
122
+ type: z.ZodLiteral<"bool_or">;
123
+ vars: z.ZodArray<z.ZodString>;
124
+ }, z.core.$strip>, z.ZodObject<{
125
+ type: z.ZodLiteral<"bool_and">;
126
+ vars: z.ZodArray<z.ZodString>;
127
+ }, z.core.$strip>, z.ZodObject<{
128
+ type: z.ZodLiteral<"no_overlap">;
129
+ intervals: z.ZodArray<z.ZodString>;
130
+ }, z.core.$strip>]>;
131
+ export declare const SolverObjectiveSchema: z.ZodObject<{
132
+ sense: z.ZodUnion<readonly [z.ZodLiteral<"minimize">, z.ZodLiteral<"maximize">]>;
133
+ terms: z.ZodArray<z.ZodObject<{
134
+ var: z.ZodString;
135
+ coeff: z.ZodNumber;
136
+ }, z.core.$strip>>;
137
+ }, z.core.$strip>;
138
+ export declare const SolverOptionsSchema: z.ZodObject<{
139
+ timeLimitSeconds: z.ZodOptional<z.ZodNumber>;
140
+ solutionLimit: z.ZodOptional<z.ZodNumber>;
141
+ }, z.core.$strip>;
142
+ export declare const SolverRequestSchema: z.ZodObject<{
143
+ variables: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
144
+ type: z.ZodLiteral<"bool">;
145
+ name: z.ZodString;
146
+ }, z.core.$strip>, z.ZodObject<{
147
+ type: z.ZodLiteral<"int">;
148
+ name: z.ZodString;
149
+ min: z.ZodNumber;
150
+ max: z.ZodNumber;
151
+ }, z.core.$strip>, z.ZodObject<{
152
+ type: z.ZodLiteral<"interval">;
153
+ name: z.ZodString;
154
+ start: z.ZodNumber;
155
+ end: z.ZodNumber;
156
+ size: z.ZodNumber;
157
+ presenceVar: z.ZodOptional<z.ZodString>;
158
+ }, z.core.$strip>]>>;
159
+ constraints: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
160
+ type: z.ZodLiteral<"linear">;
161
+ terms: z.ZodArray<z.ZodObject<{
162
+ var: z.ZodString;
163
+ coeff: z.ZodNumber;
164
+ }, z.core.$strip>>;
165
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">, z.ZodLiteral<"==">]>;
166
+ rhs: z.ZodNumber;
167
+ }, z.core.$strip>, z.ZodObject<{
168
+ type: z.ZodLiteral<"soft_linear">;
169
+ terms: z.ZodArray<z.ZodObject<{
170
+ var: z.ZodString;
171
+ coeff: z.ZodNumber;
172
+ }, z.core.$strip>>;
173
+ op: z.ZodUnion<readonly [z.ZodLiteral<"<=">, z.ZodLiteral<">=">]>;
174
+ rhs: z.ZodNumber;
175
+ penalty: z.ZodNumber;
176
+ id: z.ZodOptional<z.ZodString>;
177
+ }, z.core.$strip>, z.ZodObject<{
178
+ type: z.ZodLiteral<"exactly_one">;
179
+ vars: z.ZodArray<z.ZodString>;
180
+ }, z.core.$strip>, z.ZodObject<{
181
+ type: z.ZodLiteral<"at_most_one">;
182
+ vars: z.ZodArray<z.ZodString>;
183
+ }, z.core.$strip>, z.ZodObject<{
184
+ type: z.ZodLiteral<"implication">;
185
+ if: z.ZodString;
186
+ then: z.ZodString;
187
+ }, z.core.$strip>, z.ZodObject<{
188
+ type: z.ZodLiteral<"bool_or">;
189
+ vars: z.ZodArray<z.ZodString>;
190
+ }, z.core.$strip>, z.ZodObject<{
191
+ type: z.ZodLiteral<"bool_and">;
192
+ vars: z.ZodArray<z.ZodString>;
193
+ }, z.core.$strip>, z.ZodObject<{
194
+ type: z.ZodLiteral<"no_overlap">;
195
+ intervals: z.ZodArray<z.ZodString>;
196
+ }, z.core.$strip>]>>;
197
+ objective: z.ZodOptional<z.ZodObject<{
198
+ sense: z.ZodUnion<readonly [z.ZodLiteral<"minimize">, z.ZodLiteral<"maximize">]>;
199
+ terms: z.ZodArray<z.ZodObject<{
200
+ var: z.ZodString;
201
+ coeff: z.ZodNumber;
202
+ }, z.core.$strip>>;
203
+ }, z.core.$strip>>;
204
+ options: z.ZodOptional<z.ZodObject<{
205
+ timeLimitSeconds: z.ZodOptional<z.ZodNumber>;
206
+ solutionLimit: z.ZodOptional<z.ZodNumber>;
207
+ }, z.core.$strip>>;
208
+ }, z.core.$strip>;
209
+ export declare const SolverStatusSchema: z.ZodEnum<{
210
+ OPTIMAL: "OPTIMAL";
211
+ FEASIBLE: "FEASIBLE";
212
+ INFEASIBLE: "INFEASIBLE";
213
+ TIMEOUT: "TIMEOUT";
214
+ ERROR: "ERROR";
215
+ }>;
216
+ export declare const SolverStatisticsSchema: z.ZodObject<{
217
+ solveTimeMs: z.ZodOptional<z.ZodNumber>;
218
+ conflicts: z.ZodOptional<z.ZodNumber>;
219
+ branches: z.ZodOptional<z.ZodNumber>;
220
+ }, z.core.$strip>;
221
+ export declare const SoftConstraintViolationSchema: z.ZodObject<{
222
+ constraintId: z.ZodString;
223
+ violationAmount: z.ZodNumber;
224
+ targetValue: z.ZodNumber;
225
+ actualValue: z.ZodNumber;
226
+ }, z.core.$strip>;
227
+ export declare const SolverResponseSchema: z.ZodObject<{
228
+ status: z.ZodEnum<{
229
+ OPTIMAL: "OPTIMAL";
230
+ FEASIBLE: "FEASIBLE";
231
+ INFEASIBLE: "INFEASIBLE";
232
+ TIMEOUT: "TIMEOUT";
233
+ ERROR: "ERROR";
234
+ }>;
235
+ values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
236
+ statistics: z.ZodOptional<z.ZodObject<{
237
+ solveTimeMs: z.ZodOptional<z.ZodNumber>;
238
+ conflicts: z.ZodOptional<z.ZodNumber>;
239
+ branches: z.ZodOptional<z.ZodNumber>;
240
+ }, z.core.$strip>>;
241
+ error: z.ZodOptional<z.ZodString>;
242
+ solutionInfo: z.ZodOptional<z.ZodString>;
243
+ softViolations: z.ZodOptional<z.ZodArray<z.ZodObject<{
244
+ constraintId: z.ZodString;
245
+ violationAmount: z.ZodNumber;
246
+ targetValue: z.ZodNumber;
247
+ actualValue: z.ZodNumber;
248
+ }, z.core.$strip>>>;
249
+ }, z.core.$strip>;
250
+ //# sourceMappingURL=client.schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.schemas.d.ts","sourceRoot":"","sources":["../src/client.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;iBAK5B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;iBAQjC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;mBAI/B,CAAC;AAMH,eAAO,MAAM,sBAAsB;;;;;;;;iBAKjC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;iBAOrC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;iBAKtC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;iBAGlC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBASjC,CAAC;AAMH,eAAO,MAAM,qBAAqB;;;;;;iBAGhC,CAAC;AAMH,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAC;AAMH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK9B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;EAAoE,CAAC;AAEpG,eAAO,MAAM,sBAAsB;;;;iBAIjC,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;iBAO/B,CAAC"}