@workingdevshero/olympia-ait-adapter 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/reader/parse-day-sheet.d.ts.map +1 -1
- package/dist/reader/parse-day-sheet.js +98 -29
- package/dist/reader/parse-day-sheet.js.map +1 -1
- package/dist/schema/program.d.ts +363 -19
- package/dist/schema/program.d.ts.map +1 -1
- package/dist/schema/program.js +110 -14
- package/dist/schema/program.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/writer/build-workbook.d.ts +1 -1
- package/dist/writer/build-workbook.d.ts.map +1 -1
- package/dist/writer/build-workbook.js +18 -12
- package/dist/writer/build-workbook.js.map +1 -1
- package/dist/writer/layout.d.ts +19 -7
- package/dist/writer/layout.d.ts.map +1 -1
- package/dist/writer/layout.js +40 -21
- package/dist/writer/layout.js.map +1 -1
- package/dist/writer/stamp-exercise.d.ts +13 -5
- package/dist/writer/stamp-exercise.d.ts.map +1 -1
- package/dist/writer/stamp-exercise.js +25 -18
- package/dist/writer/stamp-exercise.js.map +1 -1
- package/dist/writer/supplemental-template.d.ts +3 -2
- package/dist/writer/supplemental-template.d.ts.map +1 -1
- package/dist/writer/supplemental-template.js +15 -15
- package/dist/writer/supplemental-template.js.map +1 -1
- package/package.json +1 -1
- package/skills/olympia-authoring/SKILL.md +25 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/schema/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/schema/program.ts"],"names":[],"mappings":"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"}
|
package/dist/schema/program.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
const
|
|
2
|
+
const MIN_WEEK_COUNT = 1;
|
|
3
|
+
const MAX_WEEK_COUNT = 6;
|
|
3
4
|
/**
|
|
4
|
-
* A single prescription cell for one set in one week
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* encoded by notation in the cell text:
|
|
5
|
+
* A single prescription cell for one set in one week: the "Reps" column of
|
|
6
|
+
* that week. The unit is reps, time, or breaths, encoded by notation in the
|
|
7
|
+
* cell text:
|
|
8
8
|
*
|
|
9
9
|
* "12" → 12 reps
|
|
10
10
|
* "10E" → 10 reps each side
|
|
@@ -21,11 +21,27 @@ const WEEK_COUNT = 6;
|
|
|
21
21
|
export const Cell = z
|
|
22
22
|
.string()
|
|
23
23
|
.nullable()
|
|
24
|
-
.describe('A single prescription. Common formats: "12" (12 reps), "10E" (10 reps each side), ":20" (20-sec hold), ":20E" (20-sec hold each side), ":60" (60 seconds), "5 breaths" (5 breaths). Free-form circuit instructions like "x3 Rest :60" are allowed. Use null for empty cells.
|
|
24
|
+
.describe('A single prescription. Common formats: "12" (12 reps), "10E" (10 reps each side), ":20" (20-sec hold), ":20E" (20-sec hold each side), ":60" (60 seconds), "5 breaths" (5 breaths). Free-form circuit instructions like "x3 Rest :60" are allowed. Use null for empty cells. Loads and equipment settings go in `weights`, not here.');
|
|
25
|
+
/**
|
|
26
|
+
* The "Weight" column cell beside a prescription. Coaches use it for a load
|
|
27
|
+
* ("25"), and just as often for an equipment setting: a band colour ("Yel"),
|
|
28
|
+
* a box height ('12" + 2 Pads'), a rack position ("#10"). It is free text
|
|
29
|
+
* and is never interpreted.
|
|
30
|
+
*/
|
|
31
|
+
export const WeightCell = z
|
|
32
|
+
.string()
|
|
33
|
+
.nullable()
|
|
34
|
+
.describe('The Weight-column cell for one set in one week, as free text: a load ("25"), or an equipment setting such as a band colour ("Yel"), box height (\'12" + 2 Pads\') or rack position ("#10"). Use null for an empty cell — most cells are empty, because the client writes in what they lifted.');
|
|
35
|
+
export const WeightRow = z
|
|
36
|
+
.array(WeightCell)
|
|
37
|
+
.min(MIN_WEEK_COUNT)
|
|
38
|
+
.max(MAX_WEEK_COUNT)
|
|
39
|
+
.describe("One set's Weight-column cells across every week, in week order. Same length as the set row it sits beside.");
|
|
25
40
|
export const SetRow = z
|
|
26
41
|
.array(Cell)
|
|
27
|
-
.
|
|
28
|
-
.
|
|
42
|
+
.min(MIN_WEEK_COUNT)
|
|
43
|
+
.max(MAX_WEEK_COUNT)
|
|
44
|
+
.describe("One set's prescription across every week of the program, in week order. Its length is the program's week count (1-6; Olympia programs run 4 or 6 weeks) and must be the same for every set row in the program.");
|
|
29
45
|
// All object schemas are .strict(): unknown keys are rejected, not silently
|
|
30
46
|
// stripped, so agents authoring against a stale contract (e.g. the removed
|
|
31
47
|
// weekDates field) fail loudly at the tool boundary.
|
|
@@ -47,10 +63,27 @@ export const Exercise = z
|
|
|
47
63
|
sets: z
|
|
48
64
|
.array(SetRow)
|
|
49
65
|
.min(1)
|
|
50
|
-
.describe("2-D matrix of prescriptions: sets[setIdx][weekIdx]. Outer length = number of sets for this exercise (typically 3); each inner array
|
|
66
|
+
.describe("2-D matrix of prescriptions: sets[setIdx][weekIdx]. Outer length = number of sets for this exercise (typically 3); each inner array has one entry per week of the program. Set positions are coherent across weeks — sets[0] is set 1's progression across the weeks."),
|
|
67
|
+
weights: z
|
|
68
|
+
.array(WeightRow)
|
|
69
|
+
.optional()
|
|
70
|
+
.describe("Weight-column cells, same shape as `sets`: weights[setIdx][weekIdx] sits beside sets[setIdx][weekIdx]. Omit when every Weight cell is empty."),
|
|
51
71
|
})
|
|
52
72
|
.strict()
|
|
53
|
-
.
|
|
73
|
+
.superRefine((exercise, ctx) => {
|
|
74
|
+
if (!exercise.weights)
|
|
75
|
+
return;
|
|
76
|
+
const sameShape = exercise.weights.length === exercise.sets.length &&
|
|
77
|
+
exercise.weights.every((row, i) => row.length === exercise.sets[i].length);
|
|
78
|
+
if (!sameShape) {
|
|
79
|
+
ctx.addIssue({
|
|
80
|
+
code: z.ZodIssueCode.custom,
|
|
81
|
+
message: "`weights` must have the same shape as `sets`: one row per set, one cell per week.",
|
|
82
|
+
path: ["weights"],
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
.describe("One exercise in a training day, with its week-by-week, set-by-set prescription.");
|
|
54
87
|
export const SectionKind = z
|
|
55
88
|
.enum(["warmup", "main", "sportSpecific", "supplemental", "conditioning"])
|
|
56
89
|
.describe("Section type within a day. Olympia day-sheets are organized into ordered sections delimited by column-C labels.");
|
|
@@ -60,6 +93,21 @@ export const Section = z
|
|
|
60
93
|
exercises: z.array(Exercise),
|
|
61
94
|
})
|
|
62
95
|
.strict()
|
|
96
|
+
.superRefine((section, ctx) => {
|
|
97
|
+
if (section.kind !== "warmup")
|
|
98
|
+
return;
|
|
99
|
+
// An in-sheet warm-up is identified on the sheet by its "Warmup N" label
|
|
100
|
+
// row, which takes the place of any group label.
|
|
101
|
+
section.exercises.forEach((exercise, i) => {
|
|
102
|
+
if (exercise.groupLabel !== undefined) {
|
|
103
|
+
ctx.addIssue({
|
|
104
|
+
code: z.ZodIssueCode.custom,
|
|
105
|
+
message: "A warmup exercise cannot carry a groupLabel; its label row reads \"Warmup N\".",
|
|
106
|
+
path: ["exercises", i, "groupLabel"],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
})
|
|
63
111
|
.describe("An ordered group of exercises within a day.");
|
|
64
112
|
export const SupplementalNote = z
|
|
65
113
|
.object({
|
|
@@ -71,10 +119,10 @@ export const SupplementalNote = z
|
|
|
71
119
|
col: z
|
|
72
120
|
.string()
|
|
73
121
|
.regex(/^[A-Z]+$/)
|
|
74
|
-
.describe("Column letter where the cell sits. Use one of D, F, H, J
|
|
122
|
+
.describe("Column letter where the cell sits. Use the master cell of a week's single-row merge, one per week of the program: D, F, H, J for a 4-week program, plus L, N for a 6-week one. Column C is reserved for the static template labels (\"Sport Specific/\", \"Supplemental\") that the writer adds back and must not be written to here."),
|
|
75
123
|
value: z
|
|
76
124
|
.string()
|
|
77
|
-
.describe('A complete freeform phrase as the trainer would write it — e.g. "Rower 600M x 2", "Optional Cardio / Post Stretch", "200 Yard Shuttle". The supplemental area is NOT a structured per-week grid: do not split a single instruction into a label cell plus per-week metric cells. To make a phrase span the row visually, emit the same `value` in each week-column entry
|
|
125
|
+
.describe('A complete freeform phrase as the trainer would write it — e.g. "Rower 600M x 2", "Optional Cardio / Post Stretch", "200 Yard Shuttle". The supplemental area is NOT a structured per-week grid: do not split a single instruction into a label cell plus per-week metric cells. To make a phrase span the row visually, emit the same `value` in each week-column entry of that row.'),
|
|
78
126
|
})
|
|
79
127
|
.strict()
|
|
80
128
|
.describe("One freeform cell captured from (or written to) the trainer-managed Sport Specific / Supplemental area at the bottom of a day sheet. Each note is an independent (row, col, value) write; the convention is one full phrase per row, repeated across the week-column masters.");
|
|
@@ -101,7 +149,42 @@ export const Program = z
|
|
|
101
149
|
days: z.array(Day).min(1),
|
|
102
150
|
})
|
|
103
151
|
.strict()
|
|
104
|
-
.
|
|
152
|
+
.superRefine((program, ctx) => {
|
|
153
|
+
const lengths = new Set();
|
|
154
|
+
for (const day of program.days) {
|
|
155
|
+
for (const section of day.sections) {
|
|
156
|
+
for (const exercise of section.exercises) {
|
|
157
|
+
for (const row of exercise.sets)
|
|
158
|
+
lengths.add(row.length);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (lengths.size > 1) {
|
|
163
|
+
ctx.addIssue({
|
|
164
|
+
code: z.ZodIssueCode.custom,
|
|
165
|
+
message: `Every set row in a program must cover the same number of weeks; found rows of length ${[...lengths].sort().join(", ")}.`,
|
|
166
|
+
path: ["days"],
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Supplemental notes may only sit on a week's Reps master (D, F, H, …):
|
|
171
|
+
// past the last week the column is Notes or off the grid, and the reader
|
|
172
|
+
// would not read the value back.
|
|
173
|
+
const weekCount = programWeekCount(program);
|
|
174
|
+
const masters = new Set(Array.from({ length: weekCount }, (_, i) => String.fromCharCode(68 + 2 * i)));
|
|
175
|
+
program.days.forEach((day, dayIdx) => {
|
|
176
|
+
day.supplementalNotes?.forEach((note, noteIdx) => {
|
|
177
|
+
if (!masters.has(note.col)) {
|
|
178
|
+
ctx.addIssue({
|
|
179
|
+
code: z.ZodIssueCode.custom,
|
|
180
|
+
message: `Supplemental note column ${note.col} is not a week column of this ${weekCount}-week program; use one of ${[...masters].join(", ")}.`,
|
|
181
|
+
path: ["days", dayIdx, "supplementalNotes", noteIdx, "col"],
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
})
|
|
187
|
+
.describe('A complete Olympia training program. Programs run a fixed number of weeks (4 or 6 — match the client\'s previous program); every set row has one entry per week and the sheet is laid out with that many week columns. Maps 1:1 to one client XLSX workbook. The "Date:" cells in each sheet\'s header row are intentionally left blank — clients hand-write the week dates. A program is usually accompanied by a companion warm-up workbook for the same client and date, paired day-for-day.');
|
|
105
188
|
// --- Tool input/output schemas ---
|
|
106
189
|
export const ProgramXlsxToJsonInput = z
|
|
107
190
|
.object({
|
|
@@ -134,5 +217,18 @@ export const ProgramJsonToXlsxOutput = z
|
|
|
134
217
|
bytesWritten: z.number().int().nonnegative(),
|
|
135
218
|
})
|
|
136
219
|
.strict();
|
|
137
|
-
export const
|
|
220
|
+
export const DEFAULT_WEEK_COUNT = MAX_WEEK_COUNT;
|
|
221
|
+
/** The number of weeks a program covers: the length of its set rows. */
|
|
222
|
+
export function programWeekCount(program) {
|
|
223
|
+
for (const day of program.days) {
|
|
224
|
+
for (const section of day.sections) {
|
|
225
|
+
for (const exercise of section.exercises) {
|
|
226
|
+
const first = exercise.sets[0];
|
|
227
|
+
if (first)
|
|
228
|
+
return first.length;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return DEFAULT_WEEK_COUNT;
|
|
233
|
+
}
|
|
138
234
|
//# sourceMappingURL=program.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/schema/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/schema/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;KAClB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CACP,sUAAsU,CACvU,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CACP,+RAA+R,CAChS,CAAC;AAEJ,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,KAAK,CAAC,UAAU,CAAC;KACjB,GAAG,CAAC,cAAc,CAAC;KACnB,GAAG,CAAC,cAAc,CAAC;KACnB,QAAQ,CAAC,4GAA4G,CAAC,CAAC;AAE1H,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC;KACpB,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,cAAc,CAAC;KACnB,GAAG,CAAC,cAAc,CAAC;KACnB,QAAQ,CACP,gNAAgN,CACjN,CAAC;AAEJ,4EAA4E;AAC5E,2EAA2E;AAC3E,qDAAqD;AACrD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC;KACtB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,oDAAoD,CAAC;IACjE,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,KAAK,CAAC,YAAY,EAAE,yDAAyD,CAAC;SAC9E,QAAQ,EAAE;SACV,QAAQ,CACP,wIAAwI,CACzI;IACH,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uDAAuD,CAAC;IACpE,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,uQAAuQ,CACxQ;IACH,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,SAAS,CAAC;SAChB,QAAQ,EAAE;SACV,QAAQ,CACP,8IAA8I,CAC/I;CACJ,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;IAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,OAAO;IAC9B,MAAM,SAAS,GACb,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC,MAAM;QAChD,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC;IAC9E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,mFAAmF;YAC5F,IAAI,EAAE,CAAC,SAAS,CAAC;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;KACD,QAAQ,CAAC,iFAAiF,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;KACzE,QAAQ,CACP,iHAAiH,CAClH,CAAC;AAEJ,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,IAAI,EAAE,WAAW;IACjB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;CAC7B,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;IAC5B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO;IACtC,yEAAyE;IACzE,iDAAiD;IACjD,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE;QACxC,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACtC,GAAG,CAAC,QAAQ,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;gBAC3B,OAAO,EAAE,gFAAgF;gBACzF,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC;aACrC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;KACD,QAAQ,CAAC,6CAA6C,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,GAAG,EAAE;SACL,WAAW,EAAE;SACb,QAAQ,CACP,yFAAyF,CAC1F;IACH,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,KAAK,CAAC,UAAU,CAAC;SACjB,QAAQ,CACP,uUAAuU,CACxU;IACH,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,CACP,uXAAuX,CACxX;CACJ,CAAC;KACD,MAAM,EAAE;KACR,QAAQ,CACP,+QAA+Q,CAChR,CAAC;AAEJ,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,kDAAkD,CAAC;IAC/D,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,iBAAiB,EAAE,CAAC;SACjB,KAAK,CAAC,gBAAgB,CAAC;SACvB,QAAQ,EAAE;SACV,QAAQ,CACP,uWAAuW,CACxW;CACJ,CAAC;KACD,MAAM,EAAE;KACR,QAAQ,CAAC,sDAAsD,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IACtE,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,QAAQ,CACP,4HAA4H,CAC7H;IACH,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1B,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;IAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrB,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,wFAAwF,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAClI,IAAI,EAAE,CAAC,MAAM,CAAC;SACf,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,wEAAwE;IACxE,yEAAyE;IACzE,iCAAiC;IACjC,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAC7E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACnC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,QAAQ,CAAC;oBACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;oBAC3B,OAAO,EAAE,4BAA4B,IAAI,CAAC,GAAG,iCAAiC,SAAS,6BAA6B,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;oBAC9I,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,CAAC;iBAC5D,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;KACD,QAAQ,CACP,ieAAie,CACle,CAAC;AAYJ,oCAAoC;AAEpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yEAAyE,CAC1E;CACJ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CACP,2KAA2K,CAC5K;CACJ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,8FAA8F,CAC/F;CACJ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC7C,CAAC;KACD,MAAM,EAAE,CAAC;AAOZ,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEjD,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC/B,IAAI,KAAK;oBAAE,OAAO,KAAK,CAAC,MAAM,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -27,7 +27,7 @@ export function createServer() {
|
|
|
27
27
|
});
|
|
28
28
|
server.registerTool("olympia_program_json_to_xlsx", {
|
|
29
29
|
title: "Olympia Program JSON → XLSX",
|
|
30
|
-
description: 'Render an Olympia program JSON document to an .xlsx workbook on disk. The input `program` MUST conform to the strict Olympia schema (one sheet per day; 6 weeks
|
|
30
|
+
description: 'Render an Olympia program JSON document to an .xlsx workbook on disk. The input `program` MUST conform to the strict Olympia schema (one sheet per day; one entry per week in every set row, 4 or 6 weeks to match the previous program of the client; group labels match `<digit><uppercase letter>`; prescriptions are reps/time/breaths; the optional `weights` grid carries the Weight column as free text). The "Date:" header cells are always left blank for the client to hand-write. Returns the output path and bytes written.',
|
|
31
31
|
inputSchema: ProgramJsonToXlsxInput.shape,
|
|
32
32
|
outputSchema: ProgramJsonToXlsxOutput.shape,
|
|
33
33
|
}, async (raw) => {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,8BAA8B,EAC9B;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EACT,iXAAiX;QACnX,WAAW,EAAE,sBAAsB,CAAC,KAAK;QACzC,YAAY,EAAE,uBAAuB,CAAC,KAAK;KAC5C,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACxD;YACD,iBAAiB,EAAE,MAAM;SAC1B,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,8BAA8B,EAC9B;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ProgramJsonToXlsxOutput, type Program } from "../schema/program.js";
|
|
2
2
|
export declare function buildProgramWorkbook(program: Program, outputPath: string): Promise<ProgramJsonToXlsxOutput>;
|
|
3
3
|
//# sourceMappingURL=build-workbook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-workbook.d.ts","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"build-workbook.d.ts","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,OAAO,EAEb,MAAM,sBAAsB,CAAC;AA8B9B,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC,CA4JlC"}
|
|
@@ -2,7 +2,8 @@ import path from "node:path";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { promises as fs } from "node:fs";
|
|
4
4
|
import ExcelJS from "exceljs";
|
|
5
|
-
import {
|
|
5
|
+
import { programWeekCount, } from "../schema/program.js";
|
|
6
|
+
import { DATE_ROW, FIRST_EXERCISE_ROW, HEADER_ROW, LOGO_ANCHOR_TL, LOGO_PIXEL_SIZE, WARMUP_ROW, weekLayout, } from "./layout.js";
|
|
6
7
|
import { DATE_LABEL, EXERCISE_HEADER, headerPadAboveStyle, headerPadBelowStyle, NOTES_HEADER_CELL, NOTES_SPACER, REPS_HEADER, SECTION_LABEL, WARMUP_DAY, WARMUP_DAY_LAST, WEIGHT_HEADER, } from "./styles.js";
|
|
7
8
|
import { groupNumberOf, stampExercise } from "./stamp-exercise.js";
|
|
8
9
|
import { stampSupplementalTemplate } from "./supplemental-template.js";
|
|
@@ -30,10 +31,12 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
30
31
|
extension: "png",
|
|
31
32
|
})
|
|
32
33
|
: undefined;
|
|
34
|
+
const layout = weekLayout(programWeekCount(program));
|
|
35
|
+
const { weekCount, repsCols: WEEK_REPS_COLS, weightCols: WEEK_WEIGHT_COLS, notesCol: NOTES_COL } = layout;
|
|
33
36
|
for (const [dayIdx, day] of program.days.entries()) {
|
|
34
37
|
const ws = workbook.addWorksheet(day.name);
|
|
35
38
|
// Column widths
|
|
36
|
-
for (const { col, width } of
|
|
39
|
+
for (const { col, width } of layout.columnWidths) {
|
|
37
40
|
ws.getColumn(col).width = width;
|
|
38
41
|
}
|
|
39
42
|
// --- Row 2: "Date:" cells + "Notes" header ---
|
|
@@ -58,7 +61,7 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
58
61
|
for (let r = WARMUP_ROW; r < FIRST_EXERCISE_ROW; r++) {
|
|
59
62
|
Object.assign(ws.getCell(`${NOTES_COL}${r}`), NOTES_SPACER);
|
|
60
63
|
}
|
|
61
|
-
for (let i = 0; i <
|
|
64
|
+
for (let i = 0; i < weekCount; i++) {
|
|
62
65
|
ws.mergeCells(`${WEEK_REPS_COLS[i]}${DATE_ROW}:${WEEK_WEIGHT_COLS[i]}${DATE_ROW}`);
|
|
63
66
|
}
|
|
64
67
|
// --- Row 3: "Warmup" + "Warm Up #N" labels (N = day index, so
|
|
@@ -69,18 +72,18 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
69
72
|
Object.assign(c, SECTION_LABEL);
|
|
70
73
|
}
|
|
71
74
|
const warmupLabel = `Warm Up #${dayIdx + 1}`;
|
|
72
|
-
for (let i = 0; i <
|
|
75
|
+
for (let i = 0; i < weekCount; i++) {
|
|
73
76
|
const a = WEEK_REPS_COLS[i];
|
|
74
77
|
const b = WEEK_WEIGHT_COLS[i];
|
|
75
78
|
ws.mergeCells(`${a}${WARMUP_ROW}:${b}${WARMUP_ROW}`);
|
|
76
79
|
const c = ws.getCell(`${a}${WARMUP_ROW}`);
|
|
77
80
|
c.value = warmupLabel;
|
|
78
|
-
Object.assign(c, i ===
|
|
81
|
+
Object.assign(c, i === weekCount - 1 ? WARMUP_DAY_LAST : WARMUP_DAY);
|
|
79
82
|
}
|
|
80
83
|
// --- Row 4: gray padding above the "Exercise" header ---
|
|
81
84
|
{
|
|
82
85
|
Object.assign(ws.getCell(`C4`), headerPadAboveStyle("C"));
|
|
83
|
-
for (let i = 0; i <
|
|
86
|
+
for (let i = 0; i < weekCount; i++) {
|
|
84
87
|
Object.assign(ws.getCell(`${WEEK_REPS_COLS[i]}4`), headerPadAboveStyle("reps"));
|
|
85
88
|
Object.assign(ws.getCell(`${WEEK_WEIGHT_COLS[i]}4`), headerPadAboveStyle("weight"));
|
|
86
89
|
}
|
|
@@ -91,7 +94,7 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
91
94
|
c.value = "Exercise";
|
|
92
95
|
Object.assign(c, EXERCISE_HEADER);
|
|
93
96
|
}
|
|
94
|
-
for (let i = 0; i <
|
|
97
|
+
for (let i = 0; i < weekCount; i++) {
|
|
95
98
|
const reps = ws.getCell(`${WEEK_REPS_COLS[i]}${HEADER_ROW}`);
|
|
96
99
|
reps.value = "Reps";
|
|
97
100
|
Object.assign(reps, REPS_HEADER);
|
|
@@ -102,7 +105,7 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
102
105
|
// --- Row 6: gray padding below the "Exercise" header ---
|
|
103
106
|
{
|
|
104
107
|
Object.assign(ws.getCell(`C6`), headerPadBelowStyle("C"));
|
|
105
|
-
for (let i = 0; i <
|
|
108
|
+
for (let i = 0; i < weekCount; i++) {
|
|
106
109
|
Object.assign(ws.getCell(`${WEEK_REPS_COLS[i]}6`), headerPadBelowStyle("reps"));
|
|
107
110
|
Object.assign(ws.getCell(`${WEEK_WEIGHT_COLS[i]}6`), headerPadBelowStyle("weight"));
|
|
108
111
|
}
|
|
@@ -116,11 +119,11 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
116
119
|
// not be filling these in for now).
|
|
117
120
|
continue;
|
|
118
121
|
}
|
|
119
|
-
row = stampSection(ws, row, section);
|
|
122
|
+
row = stampSection(ws, row, section, layout);
|
|
120
123
|
}
|
|
121
124
|
// --- Fixed Sport Specific / Supplemental template at the bottom of
|
|
122
125
|
// the sheet, with any freeform notes the trainer/agent supplied. ---
|
|
123
|
-
row = stampSupplementalTemplate(ws, row, day.supplementalNotes);
|
|
126
|
+
row = stampSupplementalTemplate(ws, row, layout, day.supplementalNotes);
|
|
124
127
|
// Olympia logo: one-cell anchor with explicit pixel dimensions so the
|
|
125
128
|
// image keeps its native aspect ratio (a two-cell anchor stretches the
|
|
126
129
|
// image to fit the cell range, which distorts the logo vertically).
|
|
@@ -146,7 +149,7 @@ export async function buildProgramWorkbook(program, outputPath) {
|
|
|
146
149
|
* - non-last block: group-label bottom NONE (the next block's top provides
|
|
147
150
|
* the visual separator)
|
|
148
151
|
*/
|
|
149
|
-
function stampSection(ws, startRow, section) {
|
|
152
|
+
function stampSection(ws, startRow, section, layout) {
|
|
150
153
|
let row = startRow;
|
|
151
154
|
for (let i = 0; i < section.exercises.length; i++) {
|
|
152
155
|
const ex = section.exercises[i];
|
|
@@ -157,7 +160,10 @@ function stampSection(ws, startRow, section) {
|
|
|
157
160
|
? "hair"
|
|
158
161
|
: "medium";
|
|
159
162
|
const bottomBorder = i === section.exercises.length - 1 ? "medium" : "none";
|
|
160
|
-
|
|
163
|
+
// In-sheet warm-up exercises carry a "Warmup N" label where a main
|
|
164
|
+
// exercise carries its group label.
|
|
165
|
+
const label = section.kind === "warmup" ? `Warmup ${i + 1}` : ex.groupLabel;
|
|
166
|
+
row = stampExercise(ws, row, ex, layout, { topBorder, bottomBorder, label });
|
|
161
167
|
}
|
|
162
168
|
return row;
|
|
163
169
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-workbook.js","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,OAAO,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"build-workbook.js","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"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"}
|
package/dist/writer/layout.d.ts
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export interface WeekLayout {
|
|
2
|
+
weekCount: number;
|
|
3
|
+
/** Reps column per week: D, F, H, … */
|
|
4
|
+
repsCols: string[];
|
|
5
|
+
/** Weight column per week: E, G, I, … */
|
|
6
|
+
weightCols: string[];
|
|
7
|
+
/** The Notes column sits immediately right of the last week pair. */
|
|
8
|
+
notesCol: string;
|
|
9
|
+
columnWidths: {
|
|
10
|
+
col: string;
|
|
11
|
+
width: number;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Column positions for a program of `weekCount` weeks. Week 1 is always
|
|
16
|
+
* D/E; each further week takes the next column pair, and the Notes column
|
|
17
|
+
* follows the last pair (L for 4 weeks, P for 6).
|
|
18
|
+
*/
|
|
19
|
+
export declare function weekLayout(weekCount: number): WeekLayout;
|
|
5
20
|
export declare const DATE_ROW = 2;
|
|
6
21
|
export declare const WARMUP_ROW = 3;
|
|
7
22
|
export declare const HEADER_ROW = 5;
|
|
8
23
|
export declare const FIRST_EXERCISE_ROW = 7;
|
|
9
|
-
export declare const WEEK_REPS_COLS: readonly ["D", "F", "H", "J", "L", "N"];
|
|
10
|
-
export declare const WEEK_WEIGHT_COLS: readonly ["E", "G", "I", "K", "M", "O"];
|
|
11
|
-
export declare const NOTES_COL = "P";
|
|
12
24
|
export declare const EXERCISE_NAME_COL = "C";
|
|
13
25
|
export declare const LOGO_ANCHOR_TL: {
|
|
14
26
|
readonly col: 5;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/writer/layout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/writer/layout.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yCAAyC;IACzC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAChD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAmBxD;AAED,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAOrC,eAAO,MAAM,cAAc;;;CAA+B,CAAC;AAC3D,eAAO,MAAM,eAAe;;;CAAsC,CAAC"}
|
package/dist/writer/layout.js
CHANGED
|
@@ -1,34 +1,53 @@
|
|
|
1
1
|
// Column widths and row positions extracted from the sample Olympia workbooks.
|
|
2
2
|
// These are constants so output is byte-stable.
|
|
3
|
-
|
|
3
|
+
const MARGIN_WIDTHS = [
|
|
4
4
|
{ col: "A", width: 0.66 },
|
|
5
5
|
{ col: "B", width: 0.66 },
|
|
6
6
|
{ col: "C", width: 25.83 },
|
|
7
|
-
{ col: "D", width: 7.66 },
|
|
8
|
-
{ col: "E", width: 8.83 },
|
|
9
|
-
{ col: "F", width: 7.66 },
|
|
10
|
-
{ col: "G", width: 7.83 },
|
|
11
|
-
{ col: "H", width: 7.66 },
|
|
12
|
-
{ col: "I", width: 8.0 },
|
|
13
|
-
{ col: "J", width: 7.66 },
|
|
14
|
-
{ col: "K", width: 8.66 },
|
|
15
|
-
{ col: "L", width: 7.66 },
|
|
16
|
-
{ col: "M", width: 9.33 },
|
|
17
|
-
{ col: "N", width: 7.66 },
|
|
18
|
-
{ col: "O", width: 8.33 },
|
|
19
|
-
// Notes column — widened from the source's 10.83 so coaching cues fit
|
|
20
|
-
// without wrapping aggressively.
|
|
21
|
-
{ col: "P", width: 18 },
|
|
22
|
-
{ col: "Q", width: 10.5 },
|
|
23
7
|
];
|
|
8
|
+
// Reps/weight widths for weeks 1-6, in week order.
|
|
9
|
+
const WEEK_PAIR_WIDTHS = [
|
|
10
|
+
[7.66, 8.83],
|
|
11
|
+
[7.66, 7.83],
|
|
12
|
+
[7.66, 8.0],
|
|
13
|
+
[7.66, 8.66],
|
|
14
|
+
[7.66, 9.33],
|
|
15
|
+
[7.66, 8.33],
|
|
16
|
+
];
|
|
17
|
+
// Notes column — widened from the source's 10.83 so coaching cues fit
|
|
18
|
+
// without wrapping aggressively.
|
|
19
|
+
const NOTES_WIDTH = 18;
|
|
20
|
+
const TRAILING_WIDTH = 10.5;
|
|
21
|
+
const FIRST_WEEK_COL_INDEX = 4; // column D
|
|
22
|
+
function colLetter(index) {
|
|
23
|
+
return String.fromCharCode(64 + index);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Column positions for a program of `weekCount` weeks. Week 1 is always
|
|
27
|
+
* D/E; each further week takes the next column pair, and the Notes column
|
|
28
|
+
* follows the last pair (L for 4 weeks, P for 6).
|
|
29
|
+
*/
|
|
30
|
+
export function weekLayout(weekCount) {
|
|
31
|
+
const repsCols = [];
|
|
32
|
+
const weightCols = [];
|
|
33
|
+
const columnWidths = [...MARGIN_WIDTHS];
|
|
34
|
+
for (let i = 0; i < weekCount; i++) {
|
|
35
|
+
const reps = colLetter(FIRST_WEEK_COL_INDEX + 2 * i);
|
|
36
|
+
const weight = colLetter(FIRST_WEEK_COL_INDEX + 2 * i + 1);
|
|
37
|
+
repsCols.push(reps);
|
|
38
|
+
weightCols.push(weight);
|
|
39
|
+
const [repsWidth, weightWidth] = WEEK_PAIR_WIDTHS[i];
|
|
40
|
+
columnWidths.push({ col: reps, width: repsWidth }, { col: weight, width: weightWidth });
|
|
41
|
+
}
|
|
42
|
+
const notesIndex = FIRST_WEEK_COL_INDEX + 2 * weekCount;
|
|
43
|
+
const notesCol = colLetter(notesIndex);
|
|
44
|
+
columnWidths.push({ col: notesCol, width: NOTES_WIDTH }, { col: colLetter(notesIndex + 1), width: TRAILING_WIDTH });
|
|
45
|
+
return { weekCount, repsCols, weightCols, notesCol, columnWidths };
|
|
46
|
+
}
|
|
24
47
|
export const DATE_ROW = 2;
|
|
25
48
|
export const WARMUP_ROW = 3;
|
|
26
49
|
export const HEADER_ROW = 5;
|
|
27
50
|
export const FIRST_EXERCISE_ROW = 7;
|
|
28
|
-
// Per-week column pairs: D/E = week 1 reps/weight, F/G = week 2, etc.
|
|
29
|
-
export const WEEK_REPS_COLS = ["D", "F", "H", "J", "L", "N"];
|
|
30
|
-
export const WEEK_WEIGHT_COLS = ["E", "G", "I", "K", "M", "O"];
|
|
31
|
-
export const NOTES_COL = "P";
|
|
32
51
|
export const EXERCISE_NAME_COL = "C";
|
|
33
52
|
// Olympia logo anchor. We use a one-cell anchor with explicit pixel
|
|
34
53
|
// dimensions (rather than a two-cell anchor) so the image keeps its native
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/writer/layout.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gDAAgD;AAEhD,MAAM,
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/writer/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type ExcelJS from "exceljs";
|
|
2
2
|
import type { Exercise } from "../schema/program.js";
|
|
3
|
+
import { type WeekLayout } from "./layout.js";
|
|
3
4
|
import { type CTopBorder, type CBottomBorder } from "./styles.js";
|
|
4
5
|
export interface StampOptions {
|
|
5
6
|
/** Border style for the top of the exercise-name (column C) cell. */
|
|
@@ -9,15 +10,22 @@ export interface StampOptions {
|
|
|
9
10
|
* "medium" only on the last exercise of a section; otherwise "none".
|
|
10
11
|
*/
|
|
11
12
|
bottomBorder: CBottomBorder;
|
|
13
|
+
/**
|
|
14
|
+
* Text for the label row under the exercise name: the group label ("1A")
|
|
15
|
+
* for a main exercise, "Warmup N" for an in-sheet warm-up exercise.
|
|
16
|
+
*/
|
|
17
|
+
label: string | undefined;
|
|
12
18
|
}
|
|
13
19
|
/**
|
|
14
20
|
* Stamps one exercise block onto the worksheet starting at `startRow`.
|
|
15
21
|
*
|
|
16
22
|
* Layout rules (N = exercise.sets.length):
|
|
17
|
-
* - With
|
|
18
|
-
* when N > 2);
|
|
19
|
-
* -
|
|
20
|
-
*
|
|
23
|
+
* - With a label: name occupies the first N−1 rows of col C (merged
|
|
24
|
+
* when N > 2); the label sits in col C of the last row.
|
|
25
|
+
* - With a label and a single set: the set sits on the name row and the
|
|
26
|
+
* label gets a row of its own below it, with empty prescription cells.
|
|
27
|
+
* - Without a label: name occupies all N rows of col C (merged when
|
|
28
|
+
* N > 1); no label row.
|
|
21
29
|
*
|
|
22
30
|
* Borders on column C (the gray bar) are driven by `topBorder` and
|
|
23
31
|
* `bottomBorder` so the caller can express "this block is the first/last
|
|
@@ -25,7 +33,7 @@ export interface StampOptions {
|
|
|
25
33
|
*
|
|
26
34
|
* @returns the next free row after the block.
|
|
27
35
|
*/
|
|
28
|
-
export declare function stampExercise(ws: ExcelJS.Worksheet, startRow: number, exercise: Exercise, opts: StampOptions): number;
|
|
36
|
+
export declare function stampExercise(ws: ExcelJS.Worksheet, startRow: number, exercise: Exercise, layout: WeekLayout, opts: StampOptions): number;
|
|
29
37
|
/** Extracts the leading numeric portion of a group label ("1A" → "1"). */
|
|
30
38
|
export declare function groupNumberOf(label: string | undefined): string | undefined;
|
|
31
39
|
//# sourceMappingURL=stamp-exercise.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stamp-exercise.d.ts","sourceRoot":"","sources":["../../src/writer/stamp-exercise.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"stamp-exercise.d.ts","sourceRoot":"","sources":["../../src/writer/stamp-exercise.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAML,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,SAAS,EAAE,UAAU,CAAC;IACtB;;;OAGG;IACH,YAAY,EAAE,aAAa,CAAC;IAC5B;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,OAAO,CAAC,SAAS,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,YAAY,GACjB,MAAM,CAqER;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAI3E"}
|