@liustack/pptfast 0.3.0 → 0.4.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 +31 -25
- package/README.zh-CN.md +30 -24
- package/dist/chunk-4W2YZPJJ.js +564 -0
- package/dist/chunk-4W2YZPJJ.js.map +1 -0
- package/dist/{chunk-ZXWCOWJI.js → chunk-7N4HGSMW.js} +2820 -1426
- package/dist/chunk-7N4HGSMW.js.map +1 -0
- package/dist/chunk-HFRNKYZ6.js +54 -0
- package/dist/chunk-HFRNKYZ6.js.map +1 -0
- package/dist/chunk-L524YK63.js +19 -0
- package/dist/chunk-L524YK63.js.map +1 -0
- package/dist/cli.js +330 -69
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +947 -200
- package/dist/index.js +42 -34
- package/dist/node.d.ts +3 -2
- package/dist/node.js +2 -2
- package/dist/pixel-audit-4DXKLFBV.js +176 -0
- package/dist/pixel-audit-4DXKLFBV.js.map +1 -0
- package/dist/registry-V079Jkry.d.ts +40 -0
- package/package.json +5 -3
- package/dist/chunk-G76EVNVT.js +0 -14
- package/dist/chunk-G76EVNVT.js.map +0 -1
- package/dist/chunk-SROEW6BH.js +0 -34
- package/dist/chunk-SROEW6BH.js.map +0 -1
- package/dist/chunk-ZXWCOWJI.js.map +0 -1
- package/dist/registry-CYKxZ0-U.d.ts +0 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export { P as PptfastPlatform, i as installPlatform } from './registry-
|
|
2
|
+
export { P as PptfastPlatform, R as RasterizedImage, i as installPlatform } from './registry-V079Jkry.js';
|
|
3
3
|
|
|
4
|
-
declare const VERSION = "0.
|
|
4
|
+
declare const VERSION = "0.4.0";
|
|
5
5
|
|
|
6
6
|
/** Error class thrown by pptfast's public API surface (validation, rendering, export). */
|
|
7
7
|
declare class PptfastError extends Error {
|
|
@@ -392,9 +392,51 @@ declare const ComponentSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
392
392
|
vs: "vs";
|
|
393
393
|
before_after: "before_after";
|
|
394
394
|
}>>;
|
|
395
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
396
|
+
type: z.ZodLiteral<"swot">;
|
|
397
|
+
strengths: z.ZodArray<z.ZodString>;
|
|
398
|
+
weaknesses: z.ZodArray<z.ZodString>;
|
|
399
|
+
opportunities: z.ZodArray<z.ZodString>;
|
|
400
|
+
threats: z.ZodArray<z.ZodString>;
|
|
401
|
+
labels: z.ZodOptional<z.ZodObject<{
|
|
402
|
+
strengths: z.ZodOptional<z.ZodString>;
|
|
403
|
+
weaknesses: z.ZodOptional<z.ZodString>;
|
|
404
|
+
opportunities: z.ZodOptional<z.ZodString>;
|
|
405
|
+
threats: z.ZodOptional<z.ZodString>;
|
|
406
|
+
}, z.core.$strict>>;
|
|
407
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
408
|
+
type: z.ZodLiteral<"bmc">;
|
|
409
|
+
key_partners: z.ZodArray<z.ZodString>;
|
|
410
|
+
key_activities: z.ZodArray<z.ZodString>;
|
|
411
|
+
key_resources: z.ZodArray<z.ZodString>;
|
|
412
|
+
value_propositions: z.ZodArray<z.ZodString>;
|
|
413
|
+
customer_relationships: z.ZodArray<z.ZodString>;
|
|
414
|
+
channels: z.ZodArray<z.ZodString>;
|
|
415
|
+
customer_segments: z.ZodArray<z.ZodString>;
|
|
416
|
+
cost_structure: z.ZodArray<z.ZodString>;
|
|
417
|
+
revenue_streams: z.ZodArray<z.ZodString>;
|
|
418
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
419
|
+
type: z.ZodLiteral<"waterfall">;
|
|
420
|
+
items: z.ZodArray<z.ZodObject<{
|
|
421
|
+
label: z.ZodString;
|
|
422
|
+
value: z.ZodNumber;
|
|
423
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
424
|
+
delta: "delta";
|
|
425
|
+
total: "total";
|
|
426
|
+
}>>;
|
|
427
|
+
}, z.core.$strict>>;
|
|
428
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
429
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
430
|
+
type: z.ZodLiteral<"gantt">;
|
|
431
|
+
items: z.ZodArray<z.ZodObject<{
|
|
432
|
+
label: z.ZodString;
|
|
433
|
+
start: z.ZodNumber;
|
|
434
|
+
end: z.ZodNumber;
|
|
435
|
+
}, z.core.$strict>>;
|
|
436
|
+
axis_labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
395
437
|
}, z.core.$strict>], "type">;
|
|
396
438
|
/**
|
|
397
|
-
* All
|
|
439
|
+
* All 28 component `type` discriminant values, derived from `ComponentSchema`
|
|
398
440
|
* itself (never hand-copied) so this list can't drift from the union above.
|
|
399
441
|
* Typed as plain `readonly string[]` rather than `Component["type"][]` —
|
|
400
442
|
* every consumer of this list (W5's plan `focus` vocabulary gate,
|
|
@@ -671,6 +713,48 @@ declare const SlideSchema: z.ZodObject<{
|
|
|
671
713
|
vs: "vs";
|
|
672
714
|
before_after: "before_after";
|
|
673
715
|
}>>;
|
|
716
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
717
|
+
type: z.ZodLiteral<"swot">;
|
|
718
|
+
strengths: z.ZodArray<z.ZodString>;
|
|
719
|
+
weaknesses: z.ZodArray<z.ZodString>;
|
|
720
|
+
opportunities: z.ZodArray<z.ZodString>;
|
|
721
|
+
threats: z.ZodArray<z.ZodString>;
|
|
722
|
+
labels: z.ZodOptional<z.ZodObject<{
|
|
723
|
+
strengths: z.ZodOptional<z.ZodString>;
|
|
724
|
+
weaknesses: z.ZodOptional<z.ZodString>;
|
|
725
|
+
opportunities: z.ZodOptional<z.ZodString>;
|
|
726
|
+
threats: z.ZodOptional<z.ZodString>;
|
|
727
|
+
}, z.core.$strict>>;
|
|
728
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
729
|
+
type: z.ZodLiteral<"bmc">;
|
|
730
|
+
key_partners: z.ZodArray<z.ZodString>;
|
|
731
|
+
key_activities: z.ZodArray<z.ZodString>;
|
|
732
|
+
key_resources: z.ZodArray<z.ZodString>;
|
|
733
|
+
value_propositions: z.ZodArray<z.ZodString>;
|
|
734
|
+
customer_relationships: z.ZodArray<z.ZodString>;
|
|
735
|
+
channels: z.ZodArray<z.ZodString>;
|
|
736
|
+
customer_segments: z.ZodArray<z.ZodString>;
|
|
737
|
+
cost_structure: z.ZodArray<z.ZodString>;
|
|
738
|
+
revenue_streams: z.ZodArray<z.ZodString>;
|
|
739
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
740
|
+
type: z.ZodLiteral<"waterfall">;
|
|
741
|
+
items: z.ZodArray<z.ZodObject<{
|
|
742
|
+
label: z.ZodString;
|
|
743
|
+
value: z.ZodNumber;
|
|
744
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
745
|
+
delta: "delta";
|
|
746
|
+
total: "total";
|
|
747
|
+
}>>;
|
|
748
|
+
}, z.core.$strict>>;
|
|
749
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
750
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
751
|
+
type: z.ZodLiteral<"gantt">;
|
|
752
|
+
items: z.ZodArray<z.ZodObject<{
|
|
753
|
+
label: z.ZodString;
|
|
754
|
+
start: z.ZodNumber;
|
|
755
|
+
end: z.ZodNumber;
|
|
756
|
+
}, z.core.$strict>>;
|
|
757
|
+
axis_labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
674
758
|
}, z.core.$strict>], "type">>>;
|
|
675
759
|
background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
676
760
|
kind: z.ZodLiteral<"color">;
|
|
@@ -715,11 +799,12 @@ declare const SlideSchema: z.ZodObject<{
|
|
|
715
799
|
right: "right";
|
|
716
800
|
}>>;
|
|
717
801
|
footnote: z.ZodOptional<z.ZodString>;
|
|
802
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
718
803
|
}, z.core.$strict>;
|
|
719
804
|
declare const PptxIRSchema: z.ZodObject<{
|
|
720
|
-
version: z.ZodDefault<z.ZodLiteral<"
|
|
805
|
+
version: z.ZodDefault<z.ZodLiteral<"4">>;
|
|
721
806
|
filename: z.ZodDefault<z.ZodString>;
|
|
722
|
-
|
|
807
|
+
narrative: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
723
808
|
theme: z.ZodDefault<z.ZodObject<{
|
|
724
809
|
id: z.ZodDefault<z.ZodString>;
|
|
725
810
|
style: z.ZodOptional<z.ZodObject<{
|
|
@@ -1071,6 +1156,48 @@ declare const PptxIRSchema: z.ZodObject<{
|
|
|
1071
1156
|
vs: "vs";
|
|
1072
1157
|
before_after: "before_after";
|
|
1073
1158
|
}>>;
|
|
1159
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1160
|
+
type: z.ZodLiteral<"swot">;
|
|
1161
|
+
strengths: z.ZodArray<z.ZodString>;
|
|
1162
|
+
weaknesses: z.ZodArray<z.ZodString>;
|
|
1163
|
+
opportunities: z.ZodArray<z.ZodString>;
|
|
1164
|
+
threats: z.ZodArray<z.ZodString>;
|
|
1165
|
+
labels: z.ZodOptional<z.ZodObject<{
|
|
1166
|
+
strengths: z.ZodOptional<z.ZodString>;
|
|
1167
|
+
weaknesses: z.ZodOptional<z.ZodString>;
|
|
1168
|
+
opportunities: z.ZodOptional<z.ZodString>;
|
|
1169
|
+
threats: z.ZodOptional<z.ZodString>;
|
|
1170
|
+
}, z.core.$strict>>;
|
|
1171
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1172
|
+
type: z.ZodLiteral<"bmc">;
|
|
1173
|
+
key_partners: z.ZodArray<z.ZodString>;
|
|
1174
|
+
key_activities: z.ZodArray<z.ZodString>;
|
|
1175
|
+
key_resources: z.ZodArray<z.ZodString>;
|
|
1176
|
+
value_propositions: z.ZodArray<z.ZodString>;
|
|
1177
|
+
customer_relationships: z.ZodArray<z.ZodString>;
|
|
1178
|
+
channels: z.ZodArray<z.ZodString>;
|
|
1179
|
+
customer_segments: z.ZodArray<z.ZodString>;
|
|
1180
|
+
cost_structure: z.ZodArray<z.ZodString>;
|
|
1181
|
+
revenue_streams: z.ZodArray<z.ZodString>;
|
|
1182
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1183
|
+
type: z.ZodLiteral<"waterfall">;
|
|
1184
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1185
|
+
label: z.ZodString;
|
|
1186
|
+
value: z.ZodNumber;
|
|
1187
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
1188
|
+
delta: "delta";
|
|
1189
|
+
total: "total";
|
|
1190
|
+
}>>;
|
|
1191
|
+
}, z.core.$strict>>;
|
|
1192
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
1193
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1194
|
+
type: z.ZodLiteral<"gantt">;
|
|
1195
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1196
|
+
label: z.ZodString;
|
|
1197
|
+
start: z.ZodNumber;
|
|
1198
|
+
end: z.ZodNumber;
|
|
1199
|
+
}, z.core.$strict>>;
|
|
1200
|
+
axis_labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1074
1201
|
}, z.core.$strict>], "type">>>;
|
|
1075
1202
|
background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1076
1203
|
kind: z.ZodLiteral<"color">;
|
|
@@ -1115,6 +1242,7 @@ declare const PptxIRSchema: z.ZodObject<{
|
|
|
1115
1242
|
right: "right";
|
|
1116
1243
|
}>>;
|
|
1117
1244
|
footnote: z.ZodOptional<z.ZodString>;
|
|
1245
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
1118
1246
|
}, z.core.$strict>>;
|
|
1119
1247
|
}, z.core.$strict>;
|
|
1120
1248
|
type PptxIR = z.infer<typeof PptxIRSchema>;
|
|
@@ -1134,8 +1262,9 @@ interface ValidationIssue {
|
|
|
1134
1262
|
* whole-branch review finding 2: the README already claimed "validation
|
|
1135
1263
|
* error messages reference [a slide] by [its] id"; this is what makes
|
|
1136
1264
|
* that true. Set by every page-scoped issue producer
|
|
1137
|
-
* ({@link checkLayoutApplicability},
|
|
1138
|
-
* translation in {@link validateIr},
|
|
1265
|
+
* ({@link checkLayoutApplicability}, {@link checkBoundaryPageContent},
|
|
1266
|
+
* the content-quality-gate translation in {@link validateIr},
|
|
1267
|
+
* {@link checkDuplicateSlideIds})
|
|
1139
1268
|
* when the slide in question has an `id` — absent when the slide has
|
|
1140
1269
|
* none (bare, pre-W5 IR) or the issue is deck-level, not scoped to any
|
|
1141
1270
|
* single slide. {@link formatIssues} appends it in parens after the page
|
|
@@ -1158,8 +1287,8 @@ interface ValidateResult {
|
|
|
1158
1287
|
}
|
|
1159
1288
|
/**
|
|
1160
1289
|
* Validate raw JSON against the IR schema, then — once it parses — resolve
|
|
1161
|
-
* `
|
|
1162
|
-
* `
|
|
1290
|
+
* `narrative` (`resolveNarrative`, spec §5: an unrecognized preset name is a
|
|
1291
|
+
* `narrative`-path error, page-less) and run the content-quality gate
|
|
1163
1292
|
* (`checkIrQuality`, passed the resolved axes) against the parsed IR. All
|
|
1164
1293
|
* stages must pass for `ok: true`. Quality findings are reported the same
|
|
1165
1294
|
* way as schema errors (page-scoped, 1-based). `checkIrQuality` itself tags
|
|
@@ -1171,18 +1300,35 @@ interface ValidateResult {
|
|
|
1171
1300
|
* defeat the point of wiring this in: the spec's core principle is a hard
|
|
1172
1301
|
* protocol gate, not hoped-for prompt compliance.
|
|
1173
1302
|
*
|
|
1174
|
-
* Before any of that,
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
* …)
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1182
|
-
* skips the extra walk. Purely informational: every rewrite is recorded as a
|
|
1183
|
-
* human-readable `path: alias → canonical` string and threaded onto
|
|
1303
|
+
* Before any of that, one deterministic alias pass runs
|
|
1304
|
+
* ({@link normalizeComponentAliases}, W5 task 4) for the component
|
|
1305
|
+
* field-name synonym rescue only (kpi `title`→`label`, quote
|
|
1306
|
+
* `content`→`text`, …) — a weak-model rescue for schema-internal synonym
|
|
1307
|
+
* drift, scoped to `slides[]`. It only rewrites where the canonical key is
|
|
1308
|
+
* absent, so the schema parse below never sees an alias as an "unrecognized
|
|
1309
|
+
* key" in the first place. Purely informational: every rewrite is recorded
|
|
1310
|
+
* as a human-readable `path: alias → canonical` string and threaded onto
|
|
1184
1311
|
* `ValidateResult.normalized` on *every* return path below via
|
|
1185
1312
|
* `withNormalized`, success or failure alike — it never itself gates `ok`.
|
|
1313
|
+
*
|
|
1314
|
+
* There is deliberately no root/narrative-level alias pass (spec §16,
|
|
1315
|
+
* reversing the now-superseded §15.4): a v4 document that still spells its
|
|
1316
|
+
* pre-rename vocabulary — `scenario` instead of `narrative`, `mode`/
|
|
1317
|
+
* `delivery` instead of `strategy`/`pacing`, or the old enum values
|
|
1318
|
+
* `"text"`/`"presentation"`/`"narrative"` — is not old-vocabulary
|
|
1319
|
+
* *compatibility*, it is exactly the vocabulary this rename retired, so it
|
|
1320
|
+
* hard-errors like any other unknown key or value: `scenario` fails the
|
|
1321
|
+
* schema's `.strict()` parse below as an unrecognized key, and an old enum
|
|
1322
|
+
* value (or the axis-key names `mode`/`delivery` inside `narrative`, which
|
|
1323
|
+
* the schema itself leaves open) fails `resolveNarrative`'s own runtime
|
|
1324
|
+
* check, listing the current values. `pptfast migrate` (`ir/migrate.ts`)
|
|
1325
|
+
* remains the sanctioned bridge for a genuine v3 document — see the v3 hard
|
|
1326
|
+
* reject below, which points there.
|
|
1327
|
+
*
|
|
1328
|
+
* The component-alias pass only ever runs for a document already headed for
|
|
1329
|
+
* the v4 schema — an explicit `version: "2"` or `version: "3"` is
|
|
1330
|
+
* hard-rejected first, below, before the alias pass or any schema parse
|
|
1331
|
+
* (spec §9.3: a v2/v3 document is never silently reinterpreted as v4).
|
|
1186
1332
|
*/
|
|
1187
1333
|
declare function validateIr(input: unknown): ValidateResult;
|
|
1188
1334
|
/**
|
|
@@ -1215,6 +1361,494 @@ declare function irJsonSchema(): Record<string, unknown>;
|
|
|
1215
1361
|
/** JSON Schema for style-token overrides (IR theme.style, --style files, config "style"). */
|
|
1216
1362
|
declare function styleJsonSchema(): Record<string, unknown>;
|
|
1217
1363
|
|
|
1364
|
+
/**
|
|
1365
|
+
* The frozen IR v3 top-level shape (vocabulary-v4 rename, task 1 — spec
|
|
1366
|
+
* §9.3: "v3 已冻结... 顶层字段和枚举改名必须进入新的 IR 版本,不能在 v3
|
|
1367
|
+
* 内静默改变含义"). `./index.ts`'s `PptxIRSchema` is v4 now — this module
|
|
1368
|
+
* exists only so a genuinely v3-shaped document still has somewhere to parse
|
|
1369
|
+
* against: `migrateIrV3ToV4`'s input type (`./migrate.ts`), and the
|
|
1370
|
+
* v3-hard-reject path's own tests (constructing a *valid* v3 IR to prove the
|
|
1371
|
+
* reject fires on version alone, not on some other schema defect).
|
|
1372
|
+
*
|
|
1373
|
+
* `validateIr` (`src/api.ts`) never calls this schema itself — an incoming
|
|
1374
|
+
* v3 document (`version === "3"`) is hard-rejected before any schema parse
|
|
1375
|
+
* runs at all (spec §9.3), full stop. This schema is a migration-tooling and
|
|
1376
|
+
* test fixture, not a second accepted input shape.
|
|
1377
|
+
*
|
|
1378
|
+
* Every field but `version` and `scenario` is byte-identical to `./index.ts`'s
|
|
1379
|
+
* v4 `PptxIRSchema` (spec §9.1: "其余 IR 字段保持不变") — reuses the exact
|
|
1380
|
+
* same `ThemeSchema`/`MetaSchema`/`AssetsSchema`/`BrandSchema`/`SlideSchema`
|
|
1381
|
+
* instances rather than redefining them, so there is no way for this frozen
|
|
1382
|
+
* shape to silently drift from the fields it shares with v4.
|
|
1383
|
+
*/
|
|
1384
|
+
declare const PptxIRV3Schema: z.ZodObject<{
|
|
1385
|
+
version: z.ZodDefault<z.ZodLiteral<"3">>;
|
|
1386
|
+
filename: z.ZodDefault<z.ZodString>;
|
|
1387
|
+
scenario: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
1388
|
+
theme: z.ZodDefault<z.ZodObject<{
|
|
1389
|
+
id: z.ZodDefault<z.ZodString>;
|
|
1390
|
+
style: z.ZodOptional<z.ZodObject<{
|
|
1391
|
+
colors: z.ZodOptional<z.ZodObject<{
|
|
1392
|
+
bg: z.ZodOptional<z.ZodString>;
|
|
1393
|
+
surface: z.ZodOptional<z.ZodString>;
|
|
1394
|
+
panel: z.ZodOptional<z.ZodString>;
|
|
1395
|
+
primary: z.ZodOptional<z.ZodString>;
|
|
1396
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
1397
|
+
text: z.ZodOptional<z.ZodString>;
|
|
1398
|
+
muted: z.ZodOptional<z.ZodString>;
|
|
1399
|
+
border: z.ZodOptional<z.ZodString>;
|
|
1400
|
+
chartPalette: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1401
|
+
accentPool: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1402
|
+
cardStroke: z.ZodOptional<z.ZodString>;
|
|
1403
|
+
}, z.core.$strict>>;
|
|
1404
|
+
fonts: z.ZodOptional<z.ZodObject<{
|
|
1405
|
+
heading: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1406
|
+
body: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1407
|
+
mono: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1408
|
+
}, z.core.$strict>>;
|
|
1409
|
+
shape: z.ZodOptional<z.ZodObject<{
|
|
1410
|
+
radius: z.ZodOptional<z.ZodNumber>;
|
|
1411
|
+
gapScale: z.ZodOptional<z.ZodNumber>;
|
|
1412
|
+
}, z.core.$strict>>;
|
|
1413
|
+
}, z.core.$strict>>;
|
|
1414
|
+
brand: z.ZodOptional<z.ZodObject<{
|
|
1415
|
+
suppressFooterOnCardContent: z.ZodOptional<z.ZodBoolean>;
|
|
1416
|
+
suppressFooterRule: z.ZodOptional<z.ZodBoolean>;
|
|
1417
|
+
}, z.core.$strict>>;
|
|
1418
|
+
}, z.core.$strict>>;
|
|
1419
|
+
meta: z.ZodDefault<z.ZodObject<{
|
|
1420
|
+
organization: z.ZodOptional<z.ZodString>;
|
|
1421
|
+
authors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1422
|
+
name: z.ZodString;
|
|
1423
|
+
role: z.ZodOptional<z.ZodString>;
|
|
1424
|
+
org: z.ZodOptional<z.ZodString>;
|
|
1425
|
+
}, z.core.$strict>>>;
|
|
1426
|
+
date: z.ZodOptional<z.ZodString>;
|
|
1427
|
+
version: z.ZodOptional<z.ZodString>;
|
|
1428
|
+
confidentiality: z.ZodOptional<z.ZodEnum<{
|
|
1429
|
+
public: "public";
|
|
1430
|
+
internal: "internal";
|
|
1431
|
+
confidential: "confidential";
|
|
1432
|
+
restricted: "restricted";
|
|
1433
|
+
}>>;
|
|
1434
|
+
contact: z.ZodOptional<z.ZodObject<{
|
|
1435
|
+
name: z.ZodOptional<z.ZodString>;
|
|
1436
|
+
email: z.ZodOptional<z.ZodString>;
|
|
1437
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
1438
|
+
website: z.ZodOptional<z.ZodString>;
|
|
1439
|
+
}, z.core.$strict>>;
|
|
1440
|
+
copyright: z.ZodOptional<z.ZodString>;
|
|
1441
|
+
animation: z.ZodOptional<z.ZodObject<{
|
|
1442
|
+
transition: z.ZodOptional<z.ZodEnum<{
|
|
1443
|
+
fade: "fade";
|
|
1444
|
+
push: "push";
|
|
1445
|
+
wipe: "wipe";
|
|
1446
|
+
none: "none";
|
|
1447
|
+
}>>;
|
|
1448
|
+
elements: z.ZodOptional<z.ZodEnum<{
|
|
1449
|
+
none: "none";
|
|
1450
|
+
auto: "auto";
|
|
1451
|
+
}>>;
|
|
1452
|
+
}, z.core.$strict>>;
|
|
1453
|
+
}, z.core.$strict>>;
|
|
1454
|
+
assets: z.ZodDefault<z.ZodObject<{
|
|
1455
|
+
images: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1456
|
+
src: z.ZodString;
|
|
1457
|
+
alt: z.ZodOptional<z.ZodString>;
|
|
1458
|
+
error: z.ZodOptional<z.ZodString>;
|
|
1459
|
+
}, z.core.$strict>>>;
|
|
1460
|
+
}, z.core.$strict>>;
|
|
1461
|
+
brand: z.ZodOptional<z.ZodObject<{
|
|
1462
|
+
logo_asset_id: z.ZodOptional<z.ZodString>;
|
|
1463
|
+
position: z.ZodOptional<z.ZodEnum<{
|
|
1464
|
+
tl: "tl";
|
|
1465
|
+
tr: "tr";
|
|
1466
|
+
bl: "bl";
|
|
1467
|
+
br: "br";
|
|
1468
|
+
}>>;
|
|
1469
|
+
}, z.core.$strict>>;
|
|
1470
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
1471
|
+
slides: z.ZodArray<z.ZodObject<{
|
|
1472
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
1473
|
+
cover: "cover";
|
|
1474
|
+
chapter: "chapter";
|
|
1475
|
+
content: "content";
|
|
1476
|
+
ending: "ending";
|
|
1477
|
+
}>>;
|
|
1478
|
+
id: z.ZodOptional<z.ZodString>;
|
|
1479
|
+
placeholder: z.ZodOptional<z.ZodLiteral<true>>;
|
|
1480
|
+
layout: z.ZodOptional<z.ZodString>;
|
|
1481
|
+
arrangement: z.ZodOptional<z.ZodEnum<{
|
|
1482
|
+
code: "code";
|
|
1483
|
+
quote: "quote";
|
|
1484
|
+
single: "single";
|
|
1485
|
+
two_column: "two_column";
|
|
1486
|
+
kpi_focus: "kpi_focus";
|
|
1487
|
+
image_focus: "image_focus";
|
|
1488
|
+
big_number: "big_number";
|
|
1489
|
+
assertion_evidence: "assertion_evidence";
|
|
1490
|
+
aside: "aside";
|
|
1491
|
+
}>>;
|
|
1492
|
+
heading: z.ZodOptional<z.ZodString>;
|
|
1493
|
+
subheading: z.ZodOptional<z.ZodString>;
|
|
1494
|
+
components: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1495
|
+
type: z.ZodLiteral<"bullets">;
|
|
1496
|
+
items: z.ZodArray<z.ZodString>;
|
|
1497
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
1498
|
+
default: "default";
|
|
1499
|
+
checklist: "checklist";
|
|
1500
|
+
numbered: "numbered";
|
|
1501
|
+
plain: "plain";
|
|
1502
|
+
divided: "divided";
|
|
1503
|
+
}>>;
|
|
1504
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1505
|
+
type: z.ZodLiteral<"paragraph">;
|
|
1506
|
+
text: z.ZodString;
|
|
1507
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1508
|
+
type: z.ZodLiteral<"quote">;
|
|
1509
|
+
text: z.ZodString;
|
|
1510
|
+
attribution: z.ZodOptional<z.ZodString>;
|
|
1511
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1512
|
+
type: z.ZodLiteral<"callout">;
|
|
1513
|
+
variant: z.ZodEnum<{
|
|
1514
|
+
info: "info";
|
|
1515
|
+
warn: "warn";
|
|
1516
|
+
tip: "tip";
|
|
1517
|
+
}>;
|
|
1518
|
+
text: z.ZodString;
|
|
1519
|
+
icon: z.ZodOptional<z.ZodEnum<{
|
|
1520
|
+
[x: string]: string;
|
|
1521
|
+
}>>;
|
|
1522
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1523
|
+
type: z.ZodLiteral<"code">;
|
|
1524
|
+
language: z.ZodString;
|
|
1525
|
+
code: z.ZodString;
|
|
1526
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1527
|
+
type: z.ZodLiteral<"kpi_cards">;
|
|
1528
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1529
|
+
value: z.ZodString;
|
|
1530
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
1531
|
+
label: z.ZodString;
|
|
1532
|
+
delta: z.ZodOptional<z.ZodEnum<{
|
|
1533
|
+
up: "up";
|
|
1534
|
+
down: "down";
|
|
1535
|
+
flat: "flat";
|
|
1536
|
+
}>>;
|
|
1537
|
+
icon: z.ZodOptional<z.ZodEnum<{
|
|
1538
|
+
[x: string]: string;
|
|
1539
|
+
}>>;
|
|
1540
|
+
source: z.ZodOptional<z.ZodString>;
|
|
1541
|
+
}, z.core.$strict>>;
|
|
1542
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1543
|
+
type: z.ZodLiteral<"chart">;
|
|
1544
|
+
chart_type: z.ZodEnum<{
|
|
1545
|
+
line: "line";
|
|
1546
|
+
dumbbell: "dumbbell";
|
|
1547
|
+
funnel: "funnel";
|
|
1548
|
+
bar: "bar";
|
|
1549
|
+
pie: "pie";
|
|
1550
|
+
}>;
|
|
1551
|
+
direction: z.ZodOptional<z.ZodEnum<{
|
|
1552
|
+
horizontal: "horizontal";
|
|
1553
|
+
vertical: "vertical";
|
|
1554
|
+
}>>;
|
|
1555
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
1556
|
+
donut: "donut";
|
|
1557
|
+
}>>;
|
|
1558
|
+
axes: z.ZodOptional<z.ZodObject<{
|
|
1559
|
+
x_title: z.ZodOptional<z.ZodString>;
|
|
1560
|
+
y_title: z.ZodOptional<z.ZodString>;
|
|
1561
|
+
show_grid: z.ZodOptional<z.ZodBoolean>;
|
|
1562
|
+
}, z.core.$strict>>;
|
|
1563
|
+
series: z.ZodArray<z.ZodObject<{
|
|
1564
|
+
name: z.ZodString;
|
|
1565
|
+
data: z.ZodArray<z.ZodObject<{
|
|
1566
|
+
x: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
1567
|
+
y: z.ZodNumber;
|
|
1568
|
+
}, z.core.$strict>>;
|
|
1569
|
+
}, z.core.$strict>>;
|
|
1570
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1571
|
+
type: z.ZodLiteral<"flowchart">;
|
|
1572
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
1573
|
+
id: z.ZodString;
|
|
1574
|
+
label: z.ZodString;
|
|
1575
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
1576
|
+
rect: "rect";
|
|
1577
|
+
diamond: "diamond";
|
|
1578
|
+
round: "round";
|
|
1579
|
+
}>>;
|
|
1580
|
+
}, z.core.$strict>>;
|
|
1581
|
+
edges: z.ZodArray<z.ZodObject<{
|
|
1582
|
+
from: z.ZodString;
|
|
1583
|
+
to: z.ZodString;
|
|
1584
|
+
label: z.ZodOptional<z.ZodString>;
|
|
1585
|
+
}, z.core.$strict>>;
|
|
1586
|
+
direction: z.ZodOptional<z.ZodEnum<{
|
|
1587
|
+
TB: "TB";
|
|
1588
|
+
TD: "TD";
|
|
1589
|
+
BT: "BT";
|
|
1590
|
+
LR: "LR";
|
|
1591
|
+
RL: "RL";
|
|
1592
|
+
}>>;
|
|
1593
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1594
|
+
type: z.ZodLiteral<"architecture">;
|
|
1595
|
+
layers: z.ZodArray<z.ZodObject<{
|
|
1596
|
+
title: z.ZodString;
|
|
1597
|
+
items: z.ZodArray<z.ZodString>;
|
|
1598
|
+
}, z.core.$strict>>;
|
|
1599
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1600
|
+
type: z.ZodLiteral<"timeline">;
|
|
1601
|
+
layout: z.ZodOptional<z.ZodEnum<{
|
|
1602
|
+
horizontal: "horizontal";
|
|
1603
|
+
vertical: "vertical";
|
|
1604
|
+
}>>;
|
|
1605
|
+
milestones: z.ZodArray<z.ZodObject<{
|
|
1606
|
+
date: z.ZodString;
|
|
1607
|
+
title: z.ZodString;
|
|
1608
|
+
desc: z.ZodOptional<z.ZodString>;
|
|
1609
|
+
highlight: z.ZodOptional<z.ZodBoolean>;
|
|
1610
|
+
}, z.core.$strict>>;
|
|
1611
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1612
|
+
type: z.ZodLiteral<"comparison">;
|
|
1613
|
+
columns: z.ZodArray<z.ZodString>;
|
|
1614
|
+
rows: z.ZodArray<z.ZodObject<{
|
|
1615
|
+
label: z.ZodString;
|
|
1616
|
+
cells: z.ZodArray<z.ZodString>;
|
|
1617
|
+
}, z.core.$strict>>;
|
|
1618
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1619
|
+
type: z.ZodLiteral<"icon_cards">;
|
|
1620
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1621
|
+
icon: z.ZodEnum<{
|
|
1622
|
+
[x: string]: string;
|
|
1623
|
+
}>;
|
|
1624
|
+
title: z.ZodString;
|
|
1625
|
+
text: z.ZodString;
|
|
1626
|
+
}, z.core.$strict>>;
|
|
1627
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1628
|
+
type: z.ZodLiteral<"row_cards">;
|
|
1629
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1630
|
+
icon: z.ZodOptional<z.ZodEnum<{
|
|
1631
|
+
[x: string]: string;
|
|
1632
|
+
}>>;
|
|
1633
|
+
title: z.ZodString;
|
|
1634
|
+
text: z.ZodOptional<z.ZodString>;
|
|
1635
|
+
sub: z.ZodOptional<z.ZodString>;
|
|
1636
|
+
highlight: z.ZodOptional<z.ZodBoolean>;
|
|
1637
|
+
}, z.core.$strict>>;
|
|
1638
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1639
|
+
type: z.ZodLiteral<"steps">;
|
|
1640
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1641
|
+
title: z.ZodString;
|
|
1642
|
+
text: z.ZodString;
|
|
1643
|
+
}, z.core.$strict>>;
|
|
1644
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1645
|
+
type: z.ZodLiteral<"rings">;
|
|
1646
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1647
|
+
label: z.ZodString;
|
|
1648
|
+
desc: z.ZodOptional<z.ZodString>;
|
|
1649
|
+
}, z.core.$strict>>;
|
|
1650
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1651
|
+
type: z.ZodLiteral<"numbered_cards">;
|
|
1652
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1653
|
+
title: z.ZodString;
|
|
1654
|
+
text: z.ZodOptional<z.ZodString>;
|
|
1655
|
+
sub: z.ZodOptional<z.ZodString>;
|
|
1656
|
+
}, z.core.$strict>>;
|
|
1657
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1658
|
+
type: z.ZodLiteral<"roadmap">;
|
|
1659
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1660
|
+
title: z.ZodString;
|
|
1661
|
+
period: z.ZodOptional<z.ZodString>;
|
|
1662
|
+
rows: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1663
|
+
label: z.ZodString;
|
|
1664
|
+
value: z.ZodString;
|
|
1665
|
+
}, z.core.$strict>>>;
|
|
1666
|
+
}, z.core.$strict>>;
|
|
1667
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1668
|
+
type: z.ZodLiteral<"matrix">;
|
|
1669
|
+
x_title: z.ZodOptional<z.ZodString>;
|
|
1670
|
+
y_title: z.ZodOptional<z.ZodString>;
|
|
1671
|
+
cols: z.ZodNumber;
|
|
1672
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1673
|
+
title: z.ZodString;
|
|
1674
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
1675
|
+
tone: z.ZodOptional<z.ZodEnum<{
|
|
1676
|
+
info: "info";
|
|
1677
|
+
accent: "accent";
|
|
1678
|
+
neutral: "neutral";
|
|
1679
|
+
}>>;
|
|
1680
|
+
}, z.core.$strict>>;
|
|
1681
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1682
|
+
type: z.ZodLiteral<"insight_panel">;
|
|
1683
|
+
title: z.ZodString;
|
|
1684
|
+
rows: z.ZodArray<z.ZodObject<{
|
|
1685
|
+
label: z.ZodString;
|
|
1686
|
+
text: z.ZodString;
|
|
1687
|
+
}, z.core.$strict>>;
|
|
1688
|
+
footnote: z.ZodOptional<z.ZodString>;
|
|
1689
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1690
|
+
type: z.ZodLiteral<"verdict_banner">;
|
|
1691
|
+
text: z.ZodString;
|
|
1692
|
+
tone: z.ZodEnum<{
|
|
1693
|
+
neutral: "neutral";
|
|
1694
|
+
positive: "positive";
|
|
1695
|
+
warning: "warning";
|
|
1696
|
+
}>;
|
|
1697
|
+
icon: z.ZodOptional<z.ZodEnum<{
|
|
1698
|
+
[x: string]: string;
|
|
1699
|
+
}>>;
|
|
1700
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1701
|
+
type: z.ZodLiteral<"citation">;
|
|
1702
|
+
sources: z.ZodArray<z.ZodObject<{
|
|
1703
|
+
label: z.ZodString;
|
|
1704
|
+
url: z.ZodOptional<z.ZodString>;
|
|
1705
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
1706
|
+
}, z.core.$strict>>;
|
|
1707
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1708
|
+
type: z.ZodLiteral<"image">;
|
|
1709
|
+
asset_id: z.ZodString;
|
|
1710
|
+
caption: z.ZodOptional<z.ZodString>;
|
|
1711
|
+
fit: z.ZodDefault<z.ZodEnum<{
|
|
1712
|
+
cover: "cover";
|
|
1713
|
+
contain: "contain";
|
|
1714
|
+
}>>;
|
|
1715
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1716
|
+
type: z.ZodLiteral<"image_grid">;
|
|
1717
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1718
|
+
asset_id: z.ZodString;
|
|
1719
|
+
caption: z.ZodOptional<z.ZodString>;
|
|
1720
|
+
}, z.core.$strict>>;
|
|
1721
|
+
emphasis: z.ZodOptional<z.ZodEnum<{
|
|
1722
|
+
none: "none";
|
|
1723
|
+
first: "first";
|
|
1724
|
+
}>>;
|
|
1725
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1726
|
+
type: z.ZodLiteral<"image_compare">;
|
|
1727
|
+
left: z.ZodObject<{
|
|
1728
|
+
asset_id: z.ZodString;
|
|
1729
|
+
label: z.ZodString;
|
|
1730
|
+
}, z.core.$strict>;
|
|
1731
|
+
right: z.ZodObject<{
|
|
1732
|
+
asset_id: z.ZodString;
|
|
1733
|
+
label: z.ZodString;
|
|
1734
|
+
}, z.core.$strict>;
|
|
1735
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
1736
|
+
vs: "vs";
|
|
1737
|
+
before_after: "before_after";
|
|
1738
|
+
}>>;
|
|
1739
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1740
|
+
type: z.ZodLiteral<"swot">;
|
|
1741
|
+
strengths: z.ZodArray<z.ZodString>;
|
|
1742
|
+
weaknesses: z.ZodArray<z.ZodString>;
|
|
1743
|
+
opportunities: z.ZodArray<z.ZodString>;
|
|
1744
|
+
threats: z.ZodArray<z.ZodString>;
|
|
1745
|
+
labels: z.ZodOptional<z.ZodObject<{
|
|
1746
|
+
strengths: z.ZodOptional<z.ZodString>;
|
|
1747
|
+
weaknesses: z.ZodOptional<z.ZodString>;
|
|
1748
|
+
opportunities: z.ZodOptional<z.ZodString>;
|
|
1749
|
+
threats: z.ZodOptional<z.ZodString>;
|
|
1750
|
+
}, z.core.$strict>>;
|
|
1751
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1752
|
+
type: z.ZodLiteral<"bmc">;
|
|
1753
|
+
key_partners: z.ZodArray<z.ZodString>;
|
|
1754
|
+
key_activities: z.ZodArray<z.ZodString>;
|
|
1755
|
+
key_resources: z.ZodArray<z.ZodString>;
|
|
1756
|
+
value_propositions: z.ZodArray<z.ZodString>;
|
|
1757
|
+
customer_relationships: z.ZodArray<z.ZodString>;
|
|
1758
|
+
channels: z.ZodArray<z.ZodString>;
|
|
1759
|
+
customer_segments: z.ZodArray<z.ZodString>;
|
|
1760
|
+
cost_structure: z.ZodArray<z.ZodString>;
|
|
1761
|
+
revenue_streams: z.ZodArray<z.ZodString>;
|
|
1762
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1763
|
+
type: z.ZodLiteral<"waterfall">;
|
|
1764
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1765
|
+
label: z.ZodString;
|
|
1766
|
+
value: z.ZodNumber;
|
|
1767
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
1768
|
+
delta: "delta";
|
|
1769
|
+
total: "total";
|
|
1770
|
+
}>>;
|
|
1771
|
+
}, z.core.$strict>>;
|
|
1772
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
1773
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1774
|
+
type: z.ZodLiteral<"gantt">;
|
|
1775
|
+
items: z.ZodArray<z.ZodObject<{
|
|
1776
|
+
label: z.ZodString;
|
|
1777
|
+
start: z.ZodNumber;
|
|
1778
|
+
end: z.ZodNumber;
|
|
1779
|
+
}, z.core.$strict>>;
|
|
1780
|
+
axis_labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1781
|
+
}, z.core.$strict>], "type">>>;
|
|
1782
|
+
background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1783
|
+
kind: z.ZodLiteral<"color">;
|
|
1784
|
+
value: z.ZodString;
|
|
1785
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1786
|
+
kind: z.ZodLiteral<"gradient">;
|
|
1787
|
+
from: z.ZodString;
|
|
1788
|
+
to: z.ZodString;
|
|
1789
|
+
direction: z.ZodOptional<z.ZodEnum<{
|
|
1790
|
+
tb: "tb";
|
|
1791
|
+
lr: "lr";
|
|
1792
|
+
diagonal: "diagonal";
|
|
1793
|
+
}>>;
|
|
1794
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1795
|
+
kind: z.ZodLiteral<"asset">;
|
|
1796
|
+
asset_id: z.ZodString;
|
|
1797
|
+
overlay: z.ZodOptional<z.ZodObject<{
|
|
1798
|
+
color: z.ZodString;
|
|
1799
|
+
opacity: z.ZodNumber;
|
|
1800
|
+
}, z.core.$strict>>;
|
|
1801
|
+
fit: z.ZodOptional<z.ZodEnum<{
|
|
1802
|
+
cover: "cover";
|
|
1803
|
+
contain: "contain";
|
|
1804
|
+
}>>;
|
|
1805
|
+
}, z.core.$strict>], "kind">>;
|
|
1806
|
+
decor: z.ZodOptional<z.ZodObject<{
|
|
1807
|
+
kind: z.ZodEnum<{
|
|
1808
|
+
big_number: "big_number";
|
|
1809
|
+
corner_tag: "corner_tag";
|
|
1810
|
+
rule_line: "rule_line";
|
|
1811
|
+
quote_marks: "quote_marks";
|
|
1812
|
+
geo_dots: "geo_dots";
|
|
1813
|
+
}>;
|
|
1814
|
+
intensity: z.ZodOptional<z.ZodEnum<{
|
|
1815
|
+
subtle: "subtle";
|
|
1816
|
+
normal: "normal";
|
|
1817
|
+
}>>;
|
|
1818
|
+
text: z.ZodOptional<z.ZodString>;
|
|
1819
|
+
}, z.core.$strict>>;
|
|
1820
|
+
image_side: z.ZodOptional<z.ZodEnum<{
|
|
1821
|
+
left: "left";
|
|
1822
|
+
right: "right";
|
|
1823
|
+
}>>;
|
|
1824
|
+
footnote: z.ZodOptional<z.ZodString>;
|
|
1825
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
1826
|
+
}, z.core.$strict>>;
|
|
1827
|
+
}, z.core.$strict>;
|
|
1828
|
+
type PptxIRV3 = z.infer<typeof PptxIRV3Schema>;
|
|
1829
|
+
|
|
1830
|
+
/**
|
|
1831
|
+
* Deterministic, pure IR v3 → v4 migration (spec §9.1). Field-for-field,
|
|
1832
|
+
* value-for-value per the mapping in {@link migrateNarrativeInput}'s
|
|
1833
|
+
* docstring — every field this function doesn't touch (`filename`, `theme`,
|
|
1834
|
+
* `meta`, `assets`, `brand`, `seed`, `slides`) carries across by the exact
|
|
1835
|
+
* same reference it came in with, unchanged (spec §9.1: "其余 IR 字段保持不
|
|
1836
|
+
* 变"; spec §10: no weight/budget/selection/render change is in scope for
|
|
1837
|
+
* this migration, ever).
|
|
1838
|
+
*
|
|
1839
|
+
* Exported from the SDK surface (`src/index.ts`) as the deterministic
|
|
1840
|
+
* migration primitive the `pptfast migrate` CLI command (task 2) wraps —
|
|
1841
|
+
* this function itself does no I/O and never runs a model, per spec §9.3's
|
|
1842
|
+
* "只做已声明的结构映射,不运行模型,不重写内容,不重新选择 layout".
|
|
1843
|
+
*
|
|
1844
|
+
* Takes an already-parsed `PptxIRV3` (i.e. `PptxIRV3Schema.parse(...)`'s
|
|
1845
|
+
* output, defaults already applied) rather than raw `unknown` JSON — schema
|
|
1846
|
+
* validation of the v3 input is the caller's job (the CLI parses-then-
|
|
1847
|
+
* migrates; `validateIr`'s own v3 path hard-rejects before ever reaching
|
|
1848
|
+
* this function, spec §9.3, so `validateIr` itself never calls this).
|
|
1849
|
+
*/
|
|
1850
|
+
declare function migrateIrV3ToV4(v3: PptxIRV3): PptxIR;
|
|
1851
|
+
|
|
1218
1852
|
type LayoutType = "cover" | "chapter" | "content" | "ending";
|
|
1219
1853
|
interface StyleColors {
|
|
1220
1854
|
bg: string;
|
|
@@ -1361,41 +1995,44 @@ declare function getInstalledThemeIds(): readonly string[];
|
|
|
1361
1995
|
*/
|
|
1362
1996
|
declare function getThemeDefinition(id: string): ThemeDefinition;
|
|
1363
1997
|
|
|
1364
|
-
declare const
|
|
1365
|
-
declare const
|
|
1998
|
+
declare const STRATEGY_VALUES: readonly ["pyramid", "storytelling", "instructional", "showcase", "briefing"];
|
|
1999
|
+
declare const PACING_VALUES: readonly ["dense", "balanced", "spacious"];
|
|
1366
2000
|
declare const AUDIENCE_VALUES: readonly ["executive", "technical", "customer", "public"];
|
|
1367
2001
|
|
|
1368
2002
|
/**
|
|
1369
|
-
* Narrative argument style (spec §5's five-way
|
|
1370
|
-
* mode
|
|
1371
|
-
* consumed by W4's
|
|
1372
|
-
*
|
|
2003
|
+
* Narrative argument style (spec §5's five-way strategy classification,
|
|
2004
|
+
* renamed from "mode" — spec §8.1). Each strategy carries a
|
|
2005
|
+
* component/layout tendency set (soft-weight material, consumed by W4's
|
|
2006
|
+
* weighted selection — nothing consumes it this wave) and a beat policy
|
|
2007
|
+
* (renamed from "rhythm policy" — spec §2.3's deck/page beat split; consumed
|
|
2008
|
+
* by W5's spec-validate rotation gate).
|
|
1373
2009
|
*/
|
|
1374
|
-
type
|
|
2010
|
+
type Strategy = (typeof STRATEGY_VALUES)[number];
|
|
1375
2011
|
/**
|
|
1376
|
-
* Content density budget + typographic baseline (spec §5
|
|
1377
|
-
* See {@link
|
|
1378
|
-
* is one half of.
|
|
2012
|
+
* Content density budget + typographic baseline (spec §5 pacing table,
|
|
2013
|
+
* renamed from "delivery" — spec §8.1). See {@link PacingBudget} for the
|
|
2014
|
+
* dual-attribute capacity split this axis is one half of.
|
|
1379
2015
|
*/
|
|
1380
|
-
type
|
|
2016
|
+
type Pacing = (typeof PACING_VALUES)[number];
|
|
1381
2017
|
/**
|
|
1382
2018
|
* Tone anchor only (spec §5: audience is tone-anchoring only, no rendering
|
|
1383
2019
|
* effect on the IR yet). Reserved for a future lint pass (e.g. executive ×
|
|
1384
2020
|
* long paragraphs → suggest kpi_cards/verdict_banner instead). The rule set
|
|
1385
2021
|
* itself is explicitly out of scope this wave (spec §10 open questions).
|
|
2022
|
+
* Name unchanged by the vocabulary-v4 rename (spec §4.3: "audience 保持不变").
|
|
1386
2023
|
*/
|
|
1387
2024
|
type Audience = (typeof AUDIENCE_VALUES)[number];
|
|
1388
|
-
interface
|
|
1389
|
-
readonly
|
|
1390
|
-
readonly
|
|
2025
|
+
interface NarrativeProfile {
|
|
2026
|
+
readonly strategy: Strategy;
|
|
2027
|
+
readonly pacing: Pacing;
|
|
1391
2028
|
readonly audience: Audience;
|
|
1392
2029
|
}
|
|
1393
2030
|
|
|
1394
|
-
interface
|
|
1395
|
-
id:
|
|
2031
|
+
interface StrategyDefinition {
|
|
2032
|
+
id: Strategy;
|
|
1396
2033
|
/**
|
|
1397
2034
|
* Layout/component tendency set (soft-weight material). Filled row-for-row
|
|
1398
|
-
* from spec §5's
|
|
2035
|
+
* from spec §5's strategy table for W4's weighted selection step (spec §6
|
|
1399
2036
|
* step 4: in-set candidates get ×3 weight, out-of-set ×1 floor — not
|
|
1400
2037
|
* implemented yet, this module only stores the data).
|
|
1401
2038
|
*
|
|
@@ -1416,48 +2053,50 @@ interface ModeDefinition {
|
|
|
1416
2053
|
* `svg/effective-layout.ts`, next to `resolveArchetypeId`, the sole
|
|
1417
2054
|
* consumer). Deliberately a separate field from {@link tendencies} above,
|
|
1418
2055
|
* not a reinterpretation of it: `tendencies` mixes component-type names and
|
|
1419
|
-
* layout ids drawn from spec §5's
|
|
1420
|
-
*
|
|
2056
|
+
* layout ids drawn from spec §5's strategy table verbatim and also feeds W5's
|
|
2057
|
+
* spec `focus` vocabulary gate, so narrowing its meaning here would be a
|
|
1421
2058
|
* breaking change to an existing consumer. This field holds only
|
|
1422
2059
|
* `LAYOUT_REGISTRY` content-archetype ids (`svg/layouts/registry.ts`'s
|
|
1423
2060
|
* `CONTENT_LAYOUTS` keys) — cover/chapter/ending ids never appear in any
|
|
1424
|
-
*
|
|
2061
|
+
* strategy's list here, which is exactly why `resolveArchetypeId`'s weighting
|
|
1425
2062
|
* is a no-op for those three slide types (spec: "身份页个性来自 theme 不来自
|
|
1426
|
-
*
|
|
2063
|
+
* strategy,均匀取样") without needing a slide-type special case — a weight
|
|
1427
2064
|
* lookup against an id that can never match falls through to the ×1 floor
|
|
1428
2065
|
* for every candidate, uniform by construction. `tone-adaptive-content`
|
|
1429
|
-
* appears in no
|
|
1430
|
-
* content archetype meant to read as
|
|
1431
|
-
* ×1 floor too).
|
|
2066
|
+
* appears in no strategy's list either (spec's "万金油" call-out: it is the
|
|
2067
|
+
* one content archetype meant to read as strategy-neutral, so it always
|
|
2068
|
+
* gets the ×1 floor too).
|
|
1432
2069
|
*/
|
|
1433
2070
|
layoutTendencies: readonly string[];
|
|
1434
2071
|
/**
|
|
1435
|
-
*
|
|
1436
|
-
* parameterized by
|
|
1437
|
-
* briefing is exempt from a generic
|
|
1438
|
-
* an error" rule because uniform-dense
|
|
1439
|
-
* not a violation of it (spec §5's
|
|
1440
|
-
* generic same-
|
|
1441
|
-
* Not consumed this wave.
|
|
2072
|
+
* Beat template descriptor (spec §5's per-strategy beat-default column,
|
|
2073
|
+
* renamed from "rhythm" — spec §2.3), parameterized by strategy for W5's
|
|
2074
|
+
* spec-validate rotation gate — e.g. briefing is exempt from a generic
|
|
2075
|
+
* "three same-beat pages in a row is an error" rule because uniform-dense
|
|
2076
|
+
* *is* briefing's correct default, not a violation of it (spec §5's
|
|
2077
|
+
* spec-gate section calls out that a generic same-beat-streak rule would
|
|
2078
|
+
* reject briefing's own default). Not consumed this wave.
|
|
1442
2079
|
*/
|
|
1443
|
-
|
|
2080
|
+
beatPolicy: "anchor-open" | "alternate" | "repetition-ok" | "anchor-sparse" | "uniform-dense";
|
|
1444
2081
|
}
|
|
1445
|
-
declare const
|
|
2082
|
+
declare const STRATEGY_DEFINITIONS: Record<Strategy, StrategyDefinition>;
|
|
1446
2083
|
|
|
1447
|
-
interface
|
|
2084
|
+
interface PacingBudget {
|
|
1448
2085
|
/**
|
|
1449
|
-
* Body-text baseline, in px, at 1280×720 slide geometry (spec §5
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1452
|
-
* `
|
|
2086
|
+
* Body-text baseline, in px, at 1280×720 slide geometry (spec §5 pacing
|
|
2087
|
+
* table's body-baseline column). Wired into rendering as of W4 task 3
|
|
2088
|
+
* (design decision 9): `src/svg/FullSlideSvg.tsx` resolves
|
|
2089
|
+
* `PACING_BUDGETS[resolveNarrative(ir.narrative).pacing].bodyBaselinePx`
|
|
1453
2090
|
* once and passes it into `buildCtx`, which stores it as
|
|
1454
2091
|
* `ComponentCtx.bodyFontPx` — the sole font-size input for the
|
|
1455
2092
|
* paragraph/bullets/callout trio ("正文" = continuous running text).
|
|
1456
2093
|
* Every other component's own bespoke type scale, the heading system, and
|
|
1457
2094
|
* quote's fixed 26px attribution line don't read this field. Since
|
|
1458
|
-
* `balanced` (24px) is the
|
|
1459
|
-
* renders body text at 24px, not the previous fixed 20px — the
|
|
1460
|
-
* spec-sanctioned snapshot re-pin that landed alongside this
|
|
2095
|
+
* `balanced` (24px) is the narrative default, an omitted-narrative deck
|
|
2096
|
+
* now renders body text at 24px, not the previous fixed 20px — the
|
|
2097
|
+
* one-time, spec-sanctioned snapshot re-pin that landed alongside this
|
|
2098
|
+
* wiring (W4 task 3, unchanged since — vocabulary-v4 only renames this
|
|
2099
|
+
* table, it doesn't touch any of its numbers, spec §10).
|
|
1461
2100
|
*/
|
|
1462
2101
|
bodyBaselinePx: number;
|
|
1463
2102
|
/**
|
|
@@ -1476,23 +2115,24 @@ interface DeliveryBudget {
|
|
|
1476
2115
|
* (`measureTextUnits`, CJK weight = 1.0) — a visual-width-weighted
|
|
1477
2116
|
* character count, not a raw `.length`. The old physical ceiling (53,
|
|
1478
2117
|
* derived from render geometry) was deleted in W3 without a replacement
|
|
1479
|
-
* check because every
|
|
2118
|
+
* check because every pacing's editorial budget here (30/40/48) is
|
|
1480
2119
|
* already strictly tighter than it — the quality gate now applies
|
|
1481
|
-
* exactly this one number per
|
|
2120
|
+
* exactly this one number per pacing.
|
|
1482
2121
|
*/
|
|
1483
2122
|
maxUnitsPerItem: number;
|
|
1484
2123
|
};
|
|
1485
2124
|
}
|
|
1486
2125
|
/**
|
|
1487
|
-
* Pinned to spec §5's
|
|
1488
|
-
* bullets budget columns):
|
|
1489
|
-
*
|
|
2126
|
+
* Pinned to spec §5's pacing table (`bodyBaselinePx` / editorial budget /
|
|
2127
|
+
* bullets budget columns): dense 20/5/6×48, balanced 24/4/5×40, spacious
|
|
2128
|
+
* 32/3/4×30 — same three rows as the pre-rename `text`/`balanced`/
|
|
2129
|
+
* `presentation` delivery table, values byte-for-byte unchanged (spec §10).
|
|
1490
2130
|
*/
|
|
1491
|
-
declare const
|
|
2131
|
+
declare const PACING_BUDGETS: Record<Pacing, PacingBudget>;
|
|
1492
2132
|
|
|
1493
|
-
interface
|
|
2133
|
+
interface NarrativePreset {
|
|
1494
2134
|
id: string;
|
|
1495
|
-
axes:
|
|
2135
|
+
axes: NarrativeProfile;
|
|
1496
2136
|
/**
|
|
1497
2137
|
* Soft theme recommendations — a suggestion, never a hard constraint
|
|
1498
2138
|
* (spec §5). Surfaced in workflow step ① so an agent can open with a
|
|
@@ -1502,27 +2142,33 @@ interface ScenarioPreset {
|
|
|
1502
2142
|
*/
|
|
1503
2143
|
themeRecommendations: readonly string[];
|
|
1504
2144
|
}
|
|
1505
|
-
/** Pinned to spec §5's 7 named presets and their theme recommendation table. */
|
|
1506
|
-
declare const SCENARIO_PRESETS: Record<string, ScenarioPreset>;
|
|
1507
2145
|
/**
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
2146
|
+
* Pinned to spec §5's 7 named presets and their theme recommendation table.
|
|
2147
|
+
* Preset ids are unchanged by the vocabulary-v4 rename (spec §5: "预设 ID
|
|
2148
|
+
* 保持不变") — only each preset's internal axes keys/values follow the
|
|
2149
|
+
* strategy/pacing rename (e.g. `annual-review`'s `mode: "narrative"` is now
|
|
2150
|
+
* `strategy: "storytelling"`, spec §5's own worked example).
|
|
2151
|
+
*/
|
|
2152
|
+
declare const NARRATIVE_PRESETS: Record<string, NarrativePreset>;
|
|
2153
|
+
/**
|
|
2154
|
+
* = `NARRATIVE_PRESETS.general.axes` (briefing × balanced × public) — the
|
|
2155
|
+
* global default when narrative is omitted entirely (spec §5's defaults
|
|
1510
2156
|
* chain).
|
|
1511
2157
|
*/
|
|
1512
|
-
declare const
|
|
2158
|
+
declare const DEFAULT_NARRATIVE: NarrativeProfile;
|
|
1513
2159
|
/**
|
|
1514
|
-
* Resolve a
|
|
2160
|
+
* Resolve a narrative input down to concrete axes, per spec §5's design
|
|
1515
2161
|
* principle "omission gets the default, a typo is a hard error" (weak-model
|
|
1516
2162
|
* friendly: a model that leaves a field out gets a sane deck, a model that
|
|
1517
2163
|
* misspells a value gets a loud, actionable error instead of a silently
|
|
1518
2164
|
* wrong deck):
|
|
1519
2165
|
*
|
|
1520
|
-
* - `undefined` → {@link
|
|
2166
|
+
* - `undefined` → {@link DEFAULT_NARRATIVE} (the `general` preset's axes)
|
|
1521
2167
|
* - a preset id string → that preset's axes (unknown id throws
|
|
1522
2168
|
* {@link PptfastError}, listing the available preset ids)
|
|
1523
2169
|
* - a partial axes object → each axis defaults independently
|
|
1524
|
-
* (
|
|
1525
|
-
* happen to equal `
|
|
2170
|
+
* (strategy → "briefing", pacing → "balanced", audience → "public" — these
|
|
2171
|
+
* happen to equal `DEFAULT_NARRATIVE`'s values because `general` *is* that
|
|
1526
2172
|
* exact combination, but the fallback here is per-axis, not "any omitted
|
|
1527
2173
|
* axis falls back to the whole default object")
|
|
1528
2174
|
*
|
|
@@ -1530,50 +2176,64 @@ declare const DEFAULT_SCENARIO: ScenarioAxes;
|
|
|
1530
2176
|
* always throws {@link PptfastError} (never silently ignored or dropped) —
|
|
1531
2177
|
* omission and a typo are different intents, and only the former has a
|
|
1532
2178
|
* reasonable default.
|
|
2179
|
+
*
|
|
2180
|
+
* Renamed from `resolveScenario` (spec §8.1). Callers that still hold a
|
|
2181
|
+
* pre-rename `mode`/`delivery` shaped input (e.g. a v3 IR's `scenario`
|
|
2182
|
+
* field) must migrate it first — see `migrateIrV3ToV4`
|
|
2183
|
+
* (`src/ir/migrate.ts`) for the deterministic field/value mapping. A
|
|
2184
|
+
* v4-track document that still writes the old field/value spelling gets no
|
|
2185
|
+
* such rescue (spec §16, reversing the now-superseded §15.4): this function
|
|
2186
|
+
* hard-errors on it, same as any other unknown axis key or value.
|
|
1533
2187
|
*/
|
|
1534
|
-
declare function
|
|
2188
|
+
declare function resolveNarrative(input: string | Partial<NarrativeProfile> | undefined): NarrativeProfile;
|
|
1535
2189
|
|
|
1536
2190
|
/**
|
|
1537
|
-
* Deck
|
|
2191
|
+
* Deck spec schema + validation (spec §5 "plan artifact and hard gates", W5
|
|
2192
|
+
* task 2 — renamed to "Deck Spec" per the vocabulary-v4 rename, spec §6/§8.1;
|
|
2193
|
+
* "spec §N" citations throughout this file that predate this rename still
|
|
2194
|
+
* point at that original W5 design doc, not this rename's own spec — left
|
|
2195
|
+
* as historical citations, not renumbered).
|
|
1538
2196
|
*
|
|
1539
|
-
* A
|
|
1540
|
-
* "escape hatch": a bare IR v3 renders directly,
|
|
1541
|
-
* optional gate for the
|
|
1542
|
-
* This module stays pure and Node-free — no `fs`, no CLI concerns
|
|
1543
|
-
* can sit in `src/index.ts`'s dependency closure exactly like
|
|
1544
|
-
* `src/
|
|
1545
|
-
* owns the one Node-touching wrapper
|
|
1546
|
-
* {@link
|
|
2197
|
+
* A deck spec is a workflow artifact, not a render prerequisite (spec §5's
|
|
2198
|
+
* "escape hatch": a bare IR v3 renders directly, `spec validate` is a
|
|
2199
|
+
* separate, optional gate for the spec-authoring stage of the six-phase
|
|
2200
|
+
* workflow). This module stays pure and Node-free — no `fs`, no CLI concerns
|
|
2201
|
+
* — so it can sit in `src/index.ts`'s dependency closure exactly like
|
|
2202
|
+
* `src/ir` and `src/narrative` already do (`AGENTS.md`'s layout rule).
|
|
2203
|
+
* `src/cli/commands.ts` owns the one Node-touching wrapper
|
|
2204
|
+
* (`runSpecValidate`: read file, call {@link validateSpec}, format the
|
|
2205
|
+
* result).
|
|
1547
2206
|
*
|
|
1548
2207
|
* Design mirrors `api.ts`'s `validateIr`/`ValidateResult` throughout
|
|
1549
2208
|
* (structural zod pass first, then a sequential chain of hard-gate
|
|
1550
2209
|
* categories, each short-circuiting the chain on its own failure — see
|
|
1551
|
-
* {@link
|
|
1552
|
-
* for
|
|
2210
|
+
* {@link validateSpec}'s own comment for why): same overall shape, adapted
|
|
2211
|
+
* for spec pages being keyed by an author-assigned `id` instead of IR's
|
|
1553
2212
|
* positional slide index.
|
|
1554
2213
|
*/
|
|
1555
2214
|
|
|
1556
2215
|
/**
|
|
1557
2216
|
* Mirrors `SlideSchema.type` / `SlideType` (`ir/index.ts`,
|
|
1558
2217
|
* `svg/layouts/registry.ts`) exactly. Kept as an independent literal tuple
|
|
1559
|
-
* here (not imported from either) — a
|
|
2218
|
+
* here (not imported from either) — a page spec's `type` is a 4-value enum
|
|
1560
2219
|
* on its own schema, not a re-export of IR's — but the `satisfies` clause
|
|
1561
2220
|
* makes any future drift between the two a compile error instead of a
|
|
1562
2221
|
* silent mismatch.
|
|
1563
2222
|
*/
|
|
1564
2223
|
declare const PAGE_TYPES: readonly ["cover", "chapter", "content", "ending"];
|
|
1565
|
-
declare const
|
|
1566
|
-
type
|
|
1567
|
-
type
|
|
2224
|
+
declare const BEAT_VALUES: readonly ["anchor", "dense", "breathing"];
|
|
2225
|
+
type PageSpecType = (typeof PAGE_TYPES)[number];
|
|
2226
|
+
type PageBeat = (typeof BEAT_VALUES)[number];
|
|
1568
2227
|
/**
|
|
1569
|
-
* A single
|
|
1570
|
-
* own `SlideSchema` (where both default/omit for weak-model
|
|
1571
|
-
* a
|
|
1572
|
-
* assemble time (W5 task 3), so leaving either implicit
|
|
1573
|
-
* the point. `
|
|
1574
|
-
* chain ("
|
|
2228
|
+
* A single page spec (spec §5, §6). `type`/`heading` are required — unlike
|
|
2229
|
+
* IR's own `SlideSchema` (where both default/omit for weak-model
|
|
2230
|
+
* friendliness), a deck spec is the authoring artifact those fields get
|
|
2231
|
+
* *locked* from at assemble time (W5 task 3), so leaving either implicit
|
|
2232
|
+
* here would defeat the point. `beat`/`focus`/`summary` stay optional per
|
|
2233
|
+
* spec §5's defaults chain ("beat omitted → auto-rotates by page position —
|
|
2234
|
+
* focus/summary/layout/slot can all be omitted").
|
|
1575
2235
|
*/
|
|
1576
|
-
declare const
|
|
2236
|
+
declare const PageSpecSchema: z.ZodObject<{
|
|
1577
2237
|
id: z.ZodString;
|
|
1578
2238
|
type: z.ZodEnum<{
|
|
1579
2239
|
cover: "cover";
|
|
@@ -1582,7 +2242,7 @@ declare const PlanPageSchema: z.ZodObject<{
|
|
|
1582
2242
|
ending: "ending";
|
|
1583
2243
|
}>;
|
|
1584
2244
|
heading: z.ZodString;
|
|
1585
|
-
|
|
2245
|
+
beat: z.ZodOptional<z.ZodEnum<{
|
|
1586
2246
|
anchor: "anchor";
|
|
1587
2247
|
dense: "dense";
|
|
1588
2248
|
breathing: "breathing";
|
|
@@ -1590,19 +2250,27 @@ declare const PlanPageSchema: z.ZodObject<{
|
|
|
1590
2250
|
focus: z.ZodOptional<z.ZodString>;
|
|
1591
2251
|
summary: z.ZodOptional<z.ZodString>;
|
|
1592
2252
|
}, z.core.$strict>;
|
|
1593
|
-
type
|
|
2253
|
+
type PageSpec = z.infer<typeof PageSpecSchema>;
|
|
1594
2254
|
/**
|
|
1595
|
-
* Top-level deck
|
|
1596
|
-
* no schema-level `.default(...)` — same reasoning as `PptxIRSchema`'s
|
|
1597
|
-
* `
|
|
1598
|
-
* into the parsed shape, {@link
|
|
1599
|
-
* (W5 task 3) each resolve it themselves. `seed` is accepted but
|
|
1600
|
-
* unexamined by this module — "not
|
|
1601
|
-
* assemble generates and suggests writing one back on first
|
|
2255
|
+
* Top-level deck spec shape (spec §5, §6). `narrative`/`theme` deliberately
|
|
2256
|
+
* have no schema-level `.default(...)` — same reasoning as `PptxIRSchema`'s
|
|
2257
|
+
* own `narrative` field (`ir/index.ts`): the resolved value is never baked
|
|
2258
|
+
* back into the parsed shape, {@link validateSpec} (here) and, later,
|
|
2259
|
+
* assemble (W5 task 3) each resolve it themselves. `seed` is accepted but
|
|
2260
|
+
* entirely unexamined by this module — "not validateSpec's concern" (spec's
|
|
2261
|
+
* own wording): assemble generates and suggests writing one back on first
|
|
2262
|
+
* materialization.
|
|
2263
|
+
*
|
|
2264
|
+
* `version` stays the literal `"1"` (unchanged value) but now carries an
|
|
2265
|
+
* independent Deck Spec versioning scheme (spec §6: "`deck.spec.json` 使用
|
|
2266
|
+
* 独立的 spec 版本 1。它是新工件,不继承 `deck.plan.json` 的版本号语义") —
|
|
2267
|
+
* this "1" is the Deck Spec artifact's own first version, not a continuation
|
|
2268
|
+
* of the old deck-plan artifact's version counter, even though the digit is
|
|
2269
|
+
* the same.
|
|
1602
2270
|
*/
|
|
1603
|
-
declare const
|
|
2271
|
+
declare const DeckSpecSchema: z.ZodObject<{
|
|
1604
2272
|
version: z.ZodDefault<z.ZodLiteral<"1">>;
|
|
1605
|
-
|
|
2273
|
+
narrative: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
1606
2274
|
theme: z.ZodOptional<z.ZodString>;
|
|
1607
2275
|
filename: z.ZodOptional<z.ZodString>;
|
|
1608
2276
|
seed: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1659,7 +2327,7 @@ declare const DeckPlanSchema: z.ZodObject<{
|
|
|
1659
2327
|
ending: "ending";
|
|
1660
2328
|
}>;
|
|
1661
2329
|
heading: z.ZodString;
|
|
1662
|
-
|
|
2330
|
+
beat: z.ZodOptional<z.ZodEnum<{
|
|
1663
2331
|
anchor: "anchor";
|
|
1664
2332
|
dense: "dense";
|
|
1665
2333
|
breathing: "breathing";
|
|
@@ -1668,10 +2336,10 @@ declare const DeckPlanSchema: z.ZodObject<{
|
|
|
1668
2336
|
summary: z.ZodOptional<z.ZodString>;
|
|
1669
2337
|
}, z.core.$strict>>;
|
|
1670
2338
|
}, z.core.$strict>;
|
|
1671
|
-
type
|
|
1672
|
-
/** JSON Schema for the deck
|
|
1673
|
-
declare function
|
|
1674
|
-
interface
|
|
2339
|
+
type DeckSpec = z.infer<typeof DeckSpecSchema>;
|
|
2340
|
+
/** JSON Schema for the deck spec — feed this to a model before it writes one (see `pptfast schema --spec`). */
|
|
2341
|
+
declare function specJsonSchema(): Record<string, unknown>;
|
|
2342
|
+
interface SpecValidationIssue {
|
|
1675
2343
|
path: string;
|
|
1676
2344
|
message: string;
|
|
1677
2345
|
/** The offending page's `id`, when the issue is scoped to one specific
|
|
@@ -1680,53 +2348,57 @@ interface PlanValidationIssue {
|
|
|
1680
2348
|
* whose own `id` itself failed to parse. */
|
|
1681
2349
|
pageId?: string;
|
|
1682
2350
|
}
|
|
1683
|
-
interface
|
|
2351
|
+
interface SpecValidateResult {
|
|
1684
2352
|
ok: boolean;
|
|
1685
|
-
|
|
1686
|
-
errors:
|
|
2353
|
+
spec?: DeckSpec;
|
|
2354
|
+
errors: SpecValidationIssue[];
|
|
1687
2355
|
}
|
|
1688
|
-
declare function
|
|
2356
|
+
declare function formatSpecIssues(errors: SpecValidationIssue[]): string;
|
|
1689
2357
|
/**
|
|
1690
|
-
*
|
|
2358
|
+
* Deck-spec-level theme default (spec §5's defaults chain: "theme omitted →
|
|
1691
2359
|
* consulting") — the same default IR's own `theme.id` field carries
|
|
1692
2360
|
* (`ThemeSchema` in `ir/index.ts`). Exported so a caller already holding a
|
|
1693
|
-
* validated {@link
|
|
2361
|
+
* validated {@link DeckSpec} (the CLI's OK-summary line) doesn't re-derive
|
|
1694
2362
|
* the fallback itself.
|
|
1695
2363
|
*/
|
|
1696
|
-
declare function
|
|
2364
|
+
declare function resolveSpecThemeId(spec: DeckSpec): string;
|
|
1697
2365
|
/**
|
|
1698
|
-
* Deck-level page-count range per
|
|
1699
|
-
* initial values — "
|
|
1700
|
-
* tuned against real usage). Independent of `
|
|
1701
|
-
* (`
|
|
2366
|
+
* Deck-level page-count range per pacing (spec §5's pacing table,
|
|
2367
|
+
* initial values — "dense 8-30 / balanced 6-24 / spacious 4-16", not yet
|
|
2368
|
+
* tuned against real usage). Independent of `PACING_BUDGETS`
|
|
2369
|
+
* (`narrative/index.ts`, per-slide component-count/bullets editorial
|
|
1702
2370
|
* budget) — this is a separate, deck-wide page-count concern the spec calls
|
|
1703
|
-
* out as its own hard gate ("page count vs.
|
|
2371
|
+
* out as its own hard gate ("page count vs. pacing recommended range").
|
|
2372
|
+
* Message wording renamed from "delivery" to "pacing" (vocabulary-v4
|
|
2373
|
+
* residual, routed from the task 1 review) — the axis itself was already
|
|
2374
|
+
* `Pacing` at the type level, this closes the last stale word in the
|
|
2375
|
+
* error text.
|
|
1704
2376
|
*/
|
|
1705
|
-
declare const
|
|
2377
|
+
declare const SPEC_PAGE_COUNT_RANGE: Record<Pacing, {
|
|
1706
2378
|
min: number;
|
|
1707
2379
|
max: number;
|
|
1708
2380
|
}>;
|
|
1709
2381
|
/**
|
|
1710
|
-
* Validate raw JSON against the
|
|
2382
|
+
* Validate raw JSON against the spec schema, then — once it parses — run the
|
|
1711
2383
|
* spec §5 hard-gate chain. Mirrors `validateIr`'s (`api.ts`) overall shape: a
|
|
1712
2384
|
* structural zod pass first, then a sequence of isolated hard-gate
|
|
1713
2385
|
* categories, each short-circuiting the whole chain on its own failure
|
|
1714
2386
|
* (rather than accumulating errors across categories) so a later category
|
|
1715
2387
|
* never has to guess at what an earlier, already-broken one would have
|
|
1716
|
-
* meant — e.g.
|
|
1717
|
-
*
|
|
1718
|
-
* resolves cleanly. Every
|
|
1719
|
-
* warning" (spec §5's "escape hatch" section — a
|
|
2388
|
+
* meant — e.g. beat-rotation and page-count both need a resolved
|
|
2389
|
+
* narrative, so nothing past the narrative/theme stage runs until that
|
|
2390
|
+
* resolves cleanly. Every spec-gate philosophy here is "hard block, no soft
|
|
2391
|
+
* warning" (spec §5's "escape hatch" section — a spec that doesn't fit this shape
|
|
1720
2392
|
* should be authored as bare IR instead, not warned-and-shipped).
|
|
1721
2393
|
*/
|
|
1722
|
-
declare function
|
|
2394
|
+
declare function validateSpec(input: unknown): SpecValidateResult;
|
|
1723
2395
|
|
|
1724
2396
|
/**
|
|
1725
|
-
* One page's fillable content — everything a
|
|
1726
|
-
* already lock in. Deliberately excludes `type`/`heading` (
|
|
2397
|
+
* One page's fillable content — everything a page spec's `id` does *not*
|
|
2398
|
+
* already lock in. Deliberately excludes `type`/`heading` (spec-owned, see
|
|
1727
2399
|
* {@link assembleDeck}'s locked-field gate) and `subheading`/`decor`
|
|
1728
2400
|
* (legitimate `Slide` fields, but outside this record's shape by spec §7's
|
|
1729
|
-
* own layout — "pages/<id>.json contains only components" — a
|
|
2401
|
+
* own layout — "pages/<id>.json contains only components" — a spec/pages deck can't
|
|
1730
2402
|
* author either one — a hand-authored bare IR still can). Every field here is
|
|
1731
2403
|
* a same-name, same-shape subset of `Slide`'s own optional fields
|
|
1732
2404
|
* (`../ir`'s `SlideSchema`) — reused, not redeclared, so the two can't drift.
|
|
@@ -1738,15 +2410,16 @@ interface PageContent {
|
|
|
1738
2410
|
background?: BackgroundSpec;
|
|
1739
2411
|
image_side?: "left" | "right";
|
|
1740
2412
|
footnote?: string;
|
|
2413
|
+
notes?: string;
|
|
1741
2414
|
}
|
|
1742
2415
|
interface AssembleResult {
|
|
1743
2416
|
ir: PptxIR;
|
|
1744
2417
|
/**
|
|
1745
|
-
* Set only when `
|
|
2418
|
+
* Set only when `spec.seed` was absent and {@link assembleDeck} generated
|
|
1746
2419
|
* one deterministically (see the seed section of this function's doc
|
|
1747
|
-
* comment) — `undefined` when `
|
|
2420
|
+
* comment) — `undefined` when `spec.seed` was already present and simply
|
|
1748
2421
|
* passed through. The CLI shell (W5 task 5) is the one that acts on this:
|
|
1749
|
-
* suggest writing the value back into the
|
|
2422
|
+
* suggest writing the value back into the spec file, never rewrite it
|
|
1750
2423
|
* itself (assemble stays a pure function, no fs side effects here).
|
|
1751
2424
|
*/
|
|
1752
2425
|
generatedSeed?: number;
|
|
@@ -1763,20 +2436,20 @@ interface AssembleResult {
|
|
|
1763
2436
|
materializedLayoutCount?: number;
|
|
1764
2437
|
}
|
|
1765
2438
|
/**
|
|
1766
|
-
* Assemble a validated
|
|
1767
|
-
* IR. See this module's own top comment for the overall shape.
|
|
1768
|
-
* below match the W5 task-3 brief's own numbered "inject
|
|
1769
|
-
* kept in that exact order because two of them
|
|
1770
|
-
* both throw and their relative order is
|
|
1771
|
-
* doc comment alone.
|
|
2439
|
+
* Assemble a validated deck spec plus a per-page content record into a
|
|
2440
|
+
* renderable IR. See this module's own top comment for the overall shape.
|
|
2441
|
+
* Step numbers below match the W5 task-3 brief's own numbered "inject
|
|
2442
|
+
* semantics" list verbatim — kept in that exact order because two of them
|
|
2443
|
+
* (locked-field vs. orphan) both throw and their relative order is
|
|
2444
|
+
* otherwise unobservable from either doc comment alone.
|
|
1772
2445
|
*
|
|
1773
|
-
* 1. `
|
|
2446
|
+
* 1. `spec` is `unknown` (same boundary `validateSpec` itself has — a spec
|
|
1774
2447
|
* is almost always freshly `JSON.parse`d off disk by the caller) —
|
|
1775
2448
|
* invalid shape or a failed hard gate throws {@link PptfastError} with
|
|
1776
|
-
* `
|
|
2449
|
+
* `validateSpec`'s own formatted issue list, not a re-derived message.
|
|
1777
2450
|
* 2. Shape guard + locked-field protection: a `pages[id]` entry must first be
|
|
1778
2451
|
* a plain object — not `null`, an array, or a primitive — else throws.
|
|
1779
|
-
* `pages` is `unknown`-shaped off disk same as `
|
|
2452
|
+
* `pages` is `unknown`-shaped off disk same as `spec` itself (step 1), so
|
|
1780
2453
|
* a JSON `null`/string/array content value is a real possibility, not
|
|
1781
2454
|
* just a type-system hole, and `Object.hasOwn` throws its own
|
|
1782
2455
|
* uninformative native `TypeError` on `null` (and silently no-ops on a
|
|
@@ -1790,63 +2463,69 @@ interface AssembleResult {
|
|
|
1790
2463
|
* `"heading": null`-turned-`undefined` or a copy-pasted empty key is
|
|
1791
2464
|
* exactly the drift this gate exists to catch instead of silently
|
|
1792
2465
|
* ignoring.
|
|
1793
|
-
* 3. Orphan keys: a `pages` entry whose id isn't any
|
|
2466
|
+
* 3. Orphan keys: a `pages` entry whose id isn't any spec page's id. Listed
|
|
1794
2467
|
* together with a fix suggestion, checked only after every present page
|
|
1795
2468
|
* has cleared the locked-field gate (step 2) — an orphan file that
|
|
1796
2469
|
* *also* happens to redeclare `heading` reports as locked-field first.
|
|
1797
|
-
* 4. Missing pages (a
|
|
2470
|
+
* 4. Missing pages (a spec id with no `pages` entry) become a placeholder
|
|
1798
2471
|
* slide — never an error. Spec §7's own words: "assemble's precise
|
|
1799
2472
|
* semantics — a missing page always succeeds (placeholder), a structural
|
|
1800
|
-
* contradiction (orphan file / bad
|
|
2473
|
+
* contradiction (orphan file / bad spec / id conflict) errors". A
|
|
1801
2474
|
* declared `summary` becomes the placeholder's `subheading` (the one spot
|
|
1802
|
-
* `summary` — otherwise a
|
|
2475
|
+
* `summary` — otherwise a spec-only anchor, see step 5 — does reach the
|
|
1803
2476
|
* IR) so a `--draft` preview of an unfilled deck still reads as more than
|
|
1804
2477
|
* a bare "Untitled".
|
|
1805
|
-
* 5. Present pages become a full slide: `id`/`type`/`heading` from the
|
|
1806
|
-
*
|
|
1807
|
-
* {@link PageContent}'s
|
|
1808
|
-
* `
|
|
1809
|
-
* they are
|
|
2478
|
+
* 5. Present pages become a full slide: `id`/`type`/`heading` from the page
|
|
2479
|
+
* spec (never the content record — see step 2), plus whichever of
|
|
2480
|
+
* {@link PageContent}'s seven fields the content record actually set.
|
|
2481
|
+
* `beat`/`focus`/`summary` never reach the IR for a present page —
|
|
2482
|
+
* they are spec-only authoring anchors (beat/focus steer a future
|
|
1810
2483
|
* fill/select step, summary is "for the fill step's own reading only"), not slide content.
|
|
1811
|
-
* 6. Top-level: `version` is always the literal `"
|
|
1812
|
-
* unrelated to the
|
|
1813
|
-
* `
|
|
2484
|
+
* 6. Top-level: `version` is always the literal `"4"` (IR's own version,
|
|
2485
|
+
* unrelated to the deck spec's own `version: "1"`) — the deck spec's own
|
|
2486
|
+
* `narrative` field (renamed this task from `scenario`, spec §8.1's
|
|
2487
|
+
* `DeckPlan`→`DeckSpec` rename, task 2) carries across into the v4 IR's
|
|
2488
|
+
* own `narrative` field, its value already in the new strategy/pacing
|
|
2489
|
+
* vocabulary (vocabulary-v4 rename, task 1 — `plan/index.ts`'s own
|
|
2490
|
+
* `resolveNarrative` call already validates it against that vocabulary
|
|
2491
|
+
* before this function ever runs).
|
|
2492
|
+
* `theme`/`filename`/`brand`/`meta`/`seed` (step 7) carry over from the spec when
|
|
1814
2493
|
* present. When absent, this function omits the field from the raw
|
|
1815
2494
|
* object it hands to {@link PptxIRSchema} rather than re-deriving IR's
|
|
1816
2495
|
* own default value a second time — one default source of truth, the
|
|
1817
2496
|
* schema itself (e.g. `theme` omitted here becomes `{ id: "consulting" }`,
|
|
1818
2497
|
* exactly like a bare hand-authored IR that never mentions theme at all —
|
|
1819
2498
|
* not a value this function needs to know).
|
|
1820
|
-
* 7. Seed: `
|
|
2499
|
+
* 7. Seed: `spec.seed` present → passed through, `generatedSeed` stays
|
|
1821
2500
|
* `undefined` on the result. Absent → {@link generateSeed} derives one
|
|
1822
|
-
* from `filename` + the
|
|
2501
|
+
* from `filename` + the spec's own ordered page-id list (never page
|
|
1823
2502
|
* *content* — see that function's own doc comment for why), written to
|
|
1824
2503
|
* `ir.seed` *and* returned as `generatedSeed` so a CLI shell can suggest
|
|
1825
|
-
* writing it back into the
|
|
2504
|
+
* writing it back into the spec file (this function never touches disk
|
|
1826
2505
|
* itself).
|
|
1827
2506
|
* 8. Idempotence: every step above is a pure function of its inputs (no
|
|
1828
2507
|
* randomness, no wall-clock, no reliance on unordered iteration) — two
|
|
1829
|
-
* calls with structurally-equal `
|
|
2508
|
+
* calls with structurally-equal `spec`/`pages` produce deep-equal
|
|
1830
2509
|
* results, `generatedSeed` included. Exercised directly by this module's
|
|
1831
2510
|
* test suite rather than asserted here.
|
|
1832
2511
|
*/
|
|
1833
|
-
declare function assembleDeck(
|
|
2512
|
+
declare function assembleDeck(spec: unknown, pages: Record<string, PageContent>): AssembleResult;
|
|
1834
2513
|
/**
|
|
1835
|
-
* Inverse of {@link assembleDeck}: reconstructs `{
|
|
2514
|
+
* Inverse of {@link assembleDeck}: reconstructs `{ spec, pages }` from an
|
|
1836
2515
|
* existing IR well enough that `assembleDeck(...disassembleDeck(ir))`
|
|
1837
2516
|
* reproduces every slide's content — but the map is not lossless in both
|
|
1838
2517
|
* directions, only in the direction the round trip actually exercises
|
|
1839
|
-
* (IR →
|
|
2518
|
+
* (IR → spec/pages → IR). Fields with no IR-side home never survive being
|
|
1840
2519
|
* written *to* the IR in the first place, so there is nothing here to read
|
|
1841
2520
|
* back:
|
|
1842
2521
|
*
|
|
1843
|
-
* - `
|
|
1844
|
-
* both are
|
|
2522
|
+
* - `beat` and `focus` never appear on any produced {@link PageSpec} —
|
|
2523
|
+
* both are spec-only authoring anchors with no corresponding `Slide`
|
|
1845
2524
|
* field at all (see {@link assembleDeck} step 5's doc comment). Nothing
|
|
1846
2525
|
* here could recover a value that was never written anywhere.
|
|
1847
2526
|
* - `summary` is recovered *only* for a placeholder slide, by reversing
|
|
1848
2527
|
* step 4's `summary` → `subheading` injection (`slide.subheading` back to
|
|
1849
|
-
* `
|
|
2528
|
+
* `pageSpec.summary`). A non-placeholder slide's own `subheading` — a
|
|
1850
2529
|
* legitimate, independent `Slide` field a hand-authored bare IR is free to
|
|
1851
2530
|
* set — has no {@link PageContent} field to land in (spec §7's pages/
|
|
1852
2531
|
* record is deliberately narrower than `Slide` itself, see that
|
|
@@ -1855,14 +2534,14 @@ declare function assembleDeck(plan: unknown, pages: Record<string, PageContent>)
|
|
|
1855
2534
|
* a filled page) — so it is dropped. Same for `decor`: a real `Slide`
|
|
1856
2535
|
* field, absent from `PageContent`'s shape entirely.
|
|
1857
2536
|
* - `theme.style` / `theme.brand` overrides collapse to a bare theme-id
|
|
1858
|
-
* string (`
|
|
2537
|
+
* string (`DeckSpecSchema.theme` has no shape for either) — only `theme.id`
|
|
1859
2538
|
* survives. That `theme.brand` is `ThemeSchema.brand` (`BrandConfigSchema`
|
|
1860
2539
|
* — `suppressFooterOnCardContent`/`suppressFooterRule`, footer-chrome
|
|
1861
2540
|
* flags owned by the *theme*) — not to be confused with the deck-level
|
|
1862
2541
|
* `brand` field below, a different, unrelated schema despite the shared
|
|
1863
2542
|
* name.
|
|
1864
2543
|
* - `ir.assets.images` is not part of this function's return value at all —
|
|
1865
|
-
* `{
|
|
2544
|
+
* `{ spec, pages }` has no `assets` field, and this module stays zero-fs
|
|
1866
2545
|
* by design (this file's own top comment), so it has no way to write an
|
|
1867
2546
|
* `assets/` directory itself. Any `asset_id` reference inside a copied
|
|
1868
2547
|
* `components`/`background` survives untouched ({@link extractPageContent}
|
|
@@ -1881,10 +2560,10 @@ declare function assembleDeck(plan: unknown, pages: Record<string, PageContent>)
|
|
|
1881
2560
|
* collision: the top-level `brand` field (`BrandSchema` — `logo_asset_id` /
|
|
1882
2561
|
* `position`, the deck logo/position `BrandChrome` reads,
|
|
1883
2562
|
* `src/svg/BrandChrome.tsx`) is a plain passthrough on both sides
|
|
1884
|
-
* ({@link assembleDeck} step 6 reads `
|
|
1885
|
-
* function reads `ir.brand` back into `
|
|
1886
|
-
* unmodified, same as `
|
|
1887
|
-
* dropped.
|
|
2563
|
+
* ({@link assembleDeck} step 6 reads `spec.brand` into `ir.brand` — this
|
|
2564
|
+
* function reads `ir.brand` back into `spec.brand` below) — carried through
|
|
2565
|
+
* unmodified, same as `narrative`/`filename`/`seed`, never
|
|
2566
|
+
* synthesized or dropped.
|
|
1888
2567
|
*
|
|
1889
2568
|
* `layout` deserves a different kind of callout: it round-trips as plain
|
|
1890
2569
|
* content like any other field ({@link extractPageContent} copies
|
|
@@ -1913,7 +2592,7 @@ declare function assembleDeck(plan: unknown, pages: Record<string, PageContent>)
|
|
|
1913
2592
|
* {@link UNTITLED_HEADING} for a missing/blank `heading`, and a positional
|
|
1914
2593
|
* `p-<1-based-ordinal>-<type>` scheme for a missing `id` (stable across
|
|
1915
2594
|
* repeated calls on the same IR — it is a pure function of slide position
|
|
1916
|
-
* and type — but, unlike a
|
|
2595
|
+
* and type — but, unlike a spec-assigned id, *not* stable across inserting
|
|
1917
2596
|
* or reordering slides — out of scope here, since a bare IR with no `id` at
|
|
1918
2597
|
* all has no stabler identity to fall back to in the first place).
|
|
1919
2598
|
*
|
|
@@ -1932,10 +2611,44 @@ declare function assembleDeck(plan: unknown, pages: Record<string, PageContent>)
|
|
|
1932
2611
|
* function) is what actually closes the vulnerability.
|
|
1933
2612
|
*/
|
|
1934
2613
|
declare function disassembleDeck(ir: PptxIR): {
|
|
1935
|
-
|
|
2614
|
+
spec: DeckSpec;
|
|
1936
2615
|
pages: Record<string, PageContent>;
|
|
1937
2616
|
};
|
|
1938
2617
|
|
|
2618
|
+
/**
|
|
2619
|
+
* Deterministic, pure `deck.plan.json` → `deck.spec.json` migration (spec
|
|
2620
|
+
* §9.2, vocabulary-v4 rename, task 2). Mirrors `../ir/migrate.ts`'s
|
|
2621
|
+
* `migrateIrV3ToV4` in spirit — mechanical field rename only, no schema
|
|
2622
|
+
* validation, no model call, no content rewrite (same posture spec §9.3
|
|
2623
|
+
* states for the IR v3→v4 primitive: "只做已声明的结构映射,不运行模型,
|
|
2624
|
+
* 不重写内容,不重新选择 layout" — this function is that same contract
|
|
2625
|
+
* applied to the other artifact this rename touches). A caller should run
|
|
2626
|
+
* `validateSpec` (`./index.ts`) against the result to confirm it lands as a
|
|
2627
|
+
* legal deck spec, exactly as it would for a `deck.spec.json` authored by
|
|
2628
|
+
* hand — this function itself never parses against `DeckSpecSchema`.
|
|
2629
|
+
*
|
|
2630
|
+
* Field-for-field, value-for-value per spec §9.2's table:
|
|
2631
|
+
*
|
|
2632
|
+
* ```text
|
|
2633
|
+
* deck.plan.json → deck.spec.json
|
|
2634
|
+
* scenario → narrative
|
|
2635
|
+
* pages[].rhythm → pages[].beat
|
|
2636
|
+
* 其余字段 → 原样保留
|
|
2637
|
+
* ```
|
|
2638
|
+
*
|
|
2639
|
+
* Takes the raw, `JSON.parse`d `deck.plan.json` contents (`unknown`) rather
|
|
2640
|
+
* than an already-validated shape — unlike `migrateIrV3ToV4` (which takes an
|
|
2641
|
+
* already-`PptxIRV3Schema.parse`d object), there is no schema left in this
|
|
2642
|
+
* codebase a pre-rename plan file could validate against: `DeckSpecSchema`
|
|
2643
|
+
* (`./index.ts`) already requires the *post*-rename field names (`narrative`,
|
|
2644
|
+
* `beat`), so parsing a plan-shaped document against it would just fail on
|
|
2645
|
+
* the very keys this function exists to rename. Non-object input, or a
|
|
2646
|
+
* `pages` value that isn't an array, passes through completely unchanged —
|
|
2647
|
+
* reporting a malformed source file is `runMigrate`'s job
|
|
2648
|
+
* (`../cli/commands.ts`), not this mechanical rename step's.
|
|
2649
|
+
*/
|
|
2650
|
+
declare function migrateDeckPlanToSpec(raw: unknown): unknown;
|
|
2651
|
+
|
|
1939
2652
|
/**
|
|
1940
2653
|
* `pptfast audit` finding shape (v0.3 W6, spec §7 workflow ④). `page` is
|
|
1941
2654
|
* 1-based (matches `ValidationIssue.page` in `api.ts`); `slideId` is set
|
|
@@ -1946,38 +2659,72 @@ declare function disassembleDeck(ir: PptxIR): {
|
|
|
1946
2659
|
interface AuditFinding {
|
|
1947
2660
|
page: number;
|
|
1948
2661
|
slideId?: string;
|
|
1949
|
-
code: "overflow" | "out-of-bounds" | "low-contrast" | "overlap";
|
|
2662
|
+
code: "overflow" | "out-of-bounds" | "low-contrast" | "overlap" | "content-truncated" | "content-dropped";
|
|
1950
2663
|
message: string;
|
|
1951
2664
|
detail?: Record<string, unknown>;
|
|
1952
2665
|
}
|
|
2666
|
+
/**
|
|
2667
|
+
* Which check families actually ran (audit-v2 phase B, spec §4.2/§11.6) —
|
|
2668
|
+
* the one piece of the spec's original metrics design that survives into
|
|
2669
|
+
* this wave (§11.6: metrics itself deferred, "唯一现值是 checks 结构"). This
|
|
2670
|
+
* is the wave's own spirit made literal: a field can only ever be
|
|
2671
|
+
* `"completed"` once its check family genuinely ran over every audited
|
|
2672
|
+
* page, never a default that silently reads as "passed". `svg` has no
|
|
2673
|
+
* `"not-requested"` state — the deterministic SVG audit always runs, so it
|
|
2674
|
+
* is always `"completed"`. `pixels` starts `"not-requested"` and only ever
|
|
2675
|
+
* becomes `"completed"`; there is deliberately no `"failed"` value — a
|
|
2676
|
+
* failed pixel audit throws (spec §11.7's "契约层"), it never reports
|
|
2677
|
+
* itself as a completed check that happens to carry no findings.
|
|
2678
|
+
*/
|
|
2679
|
+
interface AuditChecks {
|
|
2680
|
+
svg: "completed";
|
|
2681
|
+
pixels: "not-requested" | "completed";
|
|
2682
|
+
}
|
|
1953
2683
|
interface AuditReport {
|
|
1954
2684
|
findings: AuditFinding[];
|
|
1955
2685
|
pagesAudited: number;
|
|
1956
2686
|
pagesSkipped: number;
|
|
2687
|
+
checks: AuditChecks;
|
|
2688
|
+
}
|
|
2689
|
+
/** `auditDeck`'s second parameter (audit-v2 phase B) — see that function's
|
|
2690
|
+
* own doc comment for the overload contract this shape backs. */
|
|
2691
|
+
interface AuditDeckOptions {
|
|
2692
|
+
pixels?: boolean;
|
|
1957
2693
|
}
|
|
1958
2694
|
/**
|
|
1959
|
-
*
|
|
1960
|
-
*
|
|
1961
|
-
*
|
|
1962
|
-
*
|
|
1963
|
-
*
|
|
1964
|
-
*
|
|
1965
|
-
*
|
|
1966
|
-
* `parseSvg`'s doc comment) — `auditDeck` itself never calls
|
|
1967
|
-
* `installNodePlatform()`; that's the caller's job (the CLI does it
|
|
1968
|
-
* automatically).
|
|
1969
|
-
*
|
|
1970
|
-
* Advisory, not a hard gate: `validateIr` already rejects structurally
|
|
1971
|
-
* invalid or over-dense decks before a caller ever gets this far; this
|
|
1972
|
-
* function looks for the visual problems that can still slip through a
|
|
1973
|
-
* valid deck at render time (an author-chosen near-background text color,
|
|
1974
|
-
* two components whose combined content happens to collide). A non-empty
|
|
1975
|
-
* `findings` array is a prompt for a human/agent to look, not a rejection.
|
|
2695
|
+
* The SDK entry point. Advisory, not a hard gate: `validateIr` already
|
|
2696
|
+
* rejects structurally invalid or over-dense decks before a caller ever
|
|
2697
|
+
* gets this far; this function looks for the visual problems that can still
|
|
2698
|
+
* slip through a valid deck at render time (an author-chosen near-background
|
|
2699
|
+
* text color, two components whose combined content happens to collide, a
|
|
2700
|
+
* card list that had to drop an item to fit). A non-empty `findings` array
|
|
2701
|
+
* is a prompt for a human/agent to look, not a rejection.
|
|
1976
2702
|
*
|
|
1977
2703
|
* Placeholder pages (`slide.placeholder === true`) are skipped — assemble's
|
|
1978
2704
|
* stand-in for content nobody has written yet has nothing to audit, same
|
|
1979
2705
|
* reasoning `checkIrQuality` already uses to skip them (`ir-quality.ts`).
|
|
2706
|
+
*
|
|
2707
|
+
* `auditDeck` itself never calls `installNodePlatform()`; that's the
|
|
2708
|
+
* caller's job (the CLI does it automatically).
|
|
2709
|
+
*
|
|
2710
|
+
* `opts.pixels` (audit-v2 phase B, spec §4.3/§11.7) opts into the optional
|
|
2711
|
+
* pixel-level contrast audit over image-backed text (`../svg/audit/pixel-audit.ts`)
|
|
2712
|
+
* — overloaded so the far more common omitted/`false` case keeps returning
|
|
2713
|
+
* a plain, synchronous `AuditReport` (spec §11.7's "语义层": the default
|
|
2714
|
+
* audit stays pure TS with zero added latency or Promise-wrapping), while
|
|
2715
|
+
* `pixels: true` returns a `Promise<AuditReport>` that resolves once the
|
|
2716
|
+
* rasterization pass completes. A caller holding a non-literal
|
|
2717
|
+
* `{ pixels: someBoolean }` won't match either overload directly (TypeScript
|
|
2718
|
+
* can't narrow it to one specific branch) — branch on the boolean first and
|
|
2719
|
+
* call this function with a literal in each arm, e.g. `opts.pixels ? await
|
|
2720
|
+
* auditDeck(ir, { pixels: true }) : auditDeck(ir)` (`cli/commands.ts`'s
|
|
2721
|
+
* `runAudit` does exactly this).
|
|
1980
2722
|
*/
|
|
1981
|
-
declare function auditDeck(ir: PptxIR
|
|
2723
|
+
declare function auditDeck(ir: PptxIR, opts?: {
|
|
2724
|
+
pixels?: false;
|
|
2725
|
+
}): AuditReport;
|
|
2726
|
+
declare function auditDeck(ir: PptxIR, opts: {
|
|
2727
|
+
pixels: true;
|
|
2728
|
+
}): Promise<AuditReport>;
|
|
1982
2729
|
|
|
1983
|
-
export { AUDIENCE_VALUES, type AssembleResult, type Assets, type Audience, type AuditFinding, type AuditReport, BUILTIN_THEME_IDS, type BackgroundSpec, type BrandConfig, BrandConfigSchema, COMPONENT_TYPES, type Component,
|
|
2730
|
+
export { AUDIENCE_VALUES, type AssembleResult, type Assets, type Audience, type AuditChecks, type AuditDeckOptions, type AuditFinding, type AuditReport, BUILTIN_THEME_IDS, type BackgroundSpec, type BrandConfig, BrandConfigSchema, COMPONENT_TYPES, type Component, DEFAULT_NARRATIVE, type DeckSpec, DeckSpecSchema, type Meta, NARRATIVE_PRESETS, type NarrativePreset, type NarrativeProfile, PACING_BUDGETS, PACING_VALUES, type Pacing, type PacingBudget, type PageBeat, type PageContent, type PageSpec, PageSpecSchema, type PageSpecType, PptfastError, type PptxIR, PptxIRSchema, type PptxIRV3, PptxIRV3Schema, SPEC_PAGE_COUNT_RANGE, STRATEGY_DEFINITIONS, STRATEGY_VALUES, type Slide, type SpecValidateResult, type SpecValidationIssue, type Strategy, type StrategyDefinition, type StyleOverride, StyleOverrideSchema, type ThemeDefinition, type ThemeInfo, type ThemeRegistration, ThemeSchema, VERSION, type ValidateResult, type ValidationIssue, assembleDeck, auditDeck, disassembleDeck, formatIssues, formatSpecIssues, generatePptx, getInstalledThemeIds, getThemeDefinition, irJsonSchema, listThemes, migrateDeckPlanToSpec, migrateIrV3ToV4, registerTheme, renderSlideSvg, resolveNarrative, resolveSpecThemeId, specJsonSchema, styleJsonSchema, validateIr, validateSpec };
|