mulmocast 2.6.3 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +2 -1
  2. package/assets/html/chart.html +40 -7
  3. package/lib/actions/image_agents.d.ts +6 -0
  4. package/lib/actions/image_agents.js +28 -2
  5. package/lib/actions/image_references.d.ts +1 -0
  6. package/lib/actions/image_references.js +49 -11
  7. package/lib/actions/images.d.ts +26 -0
  8. package/lib/actions/images.js +2 -0
  9. package/lib/agents/movie_genai_agent.js +36 -6
  10. package/lib/agents/movie_replicate_agent.js +20 -3
  11. package/lib/methods/mulmo_presentation_style.d.ts +6 -0
  12. package/lib/slide/layouts/index.js +3 -0
  13. package/lib/slide/layouts/waterfall.d.ts +2 -0
  14. package/lib/slide/layouts/waterfall.js +63 -0
  15. package/lib/slide/render.js +4 -1
  16. package/lib/slide/schema.d.ts +176 -0
  17. package/lib/slide/schema.js +18 -0
  18. package/lib/slide/utils.d.ts +1 -0
  19. package/lib/slide/utils.js +21 -1
  20. package/lib/types/agent.d.ts +6 -0
  21. package/lib/types/provider2agent.d.ts +6 -11
  22. package/lib/types/provider2agent.js +10 -0
  23. package/lib/types/schema.d.ts +532 -0
  24. package/lib/types/schema.js +14 -0
  25. package/lib/types/slide.d.ts +176 -0
  26. package/lib/types/slide.js +18 -0
  27. package/lib/utils/context.d.ts +167 -0
  28. package/lib/utils/html_render.js +4 -3
  29. package/lib/utils/image_plugins/chart.js +19 -6
  30. package/lib/utils/image_plugins/mermaid.js +5 -1
  31. package/package.json +7 -7
  32. package/scripts/test/test_image_prompt_reference.json +55 -0
  33. package/scripts/test/test_ir_visualizations.json +317 -0
  34. package/scripts/test/test_movie_references.json +101 -0
  35. package/scripts/test/test_plugin_features.json +151 -0
@@ -189,6 +189,8 @@ export const mulmoChartMediaSchema = z
189
189
  type: z.literal("chart"),
190
190
  title: z.string(),
191
191
  chartData: z.record(z.string(), z.any()),
192
+ style: z.string().optional(),
193
+ backgroundImage: backgroundImageSchema,
192
194
  })
193
195
  .strict();
194
196
  export const mulmoMermaidMediaSchema = z
@@ -342,6 +344,8 @@ export const mulmoImagePromptMediaSchema = z
342
344
  type: z.literal("imagePrompt"),
343
345
  prompt: z.string().min(1),
344
346
  canvasSize: z.object({ width: z.number(), height: z.number() }).strict().optional(),
347
+ referenceImageName: imageIdSchema.optional().describe("Reference another imageRefs key as input for image generation"),
348
+ referenceImage: mediaSourceSchema.optional().describe("Direct source (path/url/base64) as reference image for generation"),
345
349
  })
346
350
  .strict();
347
351
  export const mulmoImageParamsImagesValueSchema = z.union([
@@ -466,6 +470,10 @@ export const mulmoTransitionSchema = z.object({
466
470
  ]),
467
471
  duration: z.number().min(0).max(2).optional().default(0.3), // transition duration in seconds
468
472
  });
473
+ export const movieReferenceImageSchema = z.object({
474
+ imageName: imageIdSchema.describe("Reference an imageRefs key"),
475
+ referenceType: z.enum(["ASSET", "STYLE"]).describe("ASSET: scene/object/character, STYLE: aesthetics/lighting"),
476
+ });
469
477
  export const mulmoMovieParamsSchema = z.object({
470
478
  provider: text2MovieProviderSchema.optional(),
471
479
  model: z.string().optional(),
@@ -474,6 +482,12 @@ export const mulmoMovieParamsSchema = z.object({
474
482
  filters: z.array(mulmoVideoFilterSchema).optional(), // for movie.ts
475
483
  vertexai_project: z.string().optional(), // Google Cloud Project ID for Vertex AI
476
484
  vertexai_location: z.string().optional(), // Vertex AI location (default: us-central1)
485
+ firstFrameImageName: imageIdSchema.optional().describe("Reference an imageRefs key for the first frame (image-to-video input)"),
486
+ lastFrameImageName: imageIdSchema.optional().describe("Reference an imageRefs key for the last frame (image-to-video interpolation)"),
487
+ referenceImages: z
488
+ .array(movieReferenceImageSchema)
489
+ .optional()
490
+ .describe("Style/asset reference images (Veo 3.1). Mutually exclusive with imageName/lastFrameImageName"),
477
491
  });
478
492
  export const mulmoBeatSchema = z
479
493
  .object({
@@ -4284,6 +4284,74 @@ export declare const tableSlideSchema: z.ZodObject<{
4284
4284
  }, z.core.$strip>>;
4285
4285
  layout: z.ZodLiteral<"table">;
4286
4286
  }, z.core.$strip>;
4287
+ export declare const waterfallItemSchema: z.ZodObject<{
4288
+ label: z.ZodString;
4289
+ value: z.ZodNumber;
4290
+ isTotal: z.ZodOptional<z.ZodBoolean>;
4291
+ color: z.ZodOptional<z.ZodEnum<{
4292
+ success: "success";
4293
+ primary: "primary";
4294
+ accent: "accent";
4295
+ warning: "warning";
4296
+ danger: "danger";
4297
+ info: "info";
4298
+ highlight: "highlight";
4299
+ }>>;
4300
+ }, z.core.$strip>;
4301
+ export declare const waterfallSlideSchema: z.ZodObject<{
4302
+ title: z.ZodString;
4303
+ stepLabel: z.ZodOptional<z.ZodString>;
4304
+ subtitle: z.ZodOptional<z.ZodString>;
4305
+ items: z.ZodArray<z.ZodObject<{
4306
+ label: z.ZodString;
4307
+ value: z.ZodNumber;
4308
+ isTotal: z.ZodOptional<z.ZodBoolean>;
4309
+ color: z.ZodOptional<z.ZodEnum<{
4310
+ success: "success";
4311
+ primary: "primary";
4312
+ accent: "accent";
4313
+ warning: "warning";
4314
+ danger: "danger";
4315
+ info: "info";
4316
+ highlight: "highlight";
4317
+ }>>;
4318
+ }, z.core.$strip>>;
4319
+ unit: z.ZodOptional<z.ZodString>;
4320
+ callout: z.ZodOptional<z.ZodObject<{
4321
+ text: z.ZodString;
4322
+ label: z.ZodOptional<z.ZodString>;
4323
+ color: z.ZodOptional<z.ZodEnum<{
4324
+ success: "success";
4325
+ primary: "primary";
4326
+ accent: "accent";
4327
+ warning: "warning";
4328
+ danger: "danger";
4329
+ info: "info";
4330
+ highlight: "highlight";
4331
+ }>>;
4332
+ align: z.ZodOptional<z.ZodEnum<{
4333
+ left: "left";
4334
+ center: "center";
4335
+ }>>;
4336
+ leftBar: z.ZodOptional<z.ZodBoolean>;
4337
+ }, z.core.$strip>>;
4338
+ accentColor: z.ZodOptional<z.ZodEnum<{
4339
+ success: "success";
4340
+ primary: "primary";
4341
+ accent: "accent";
4342
+ warning: "warning";
4343
+ danger: "danger";
4344
+ info: "info";
4345
+ highlight: "highlight";
4346
+ }>>;
4347
+ style: z.ZodOptional<z.ZodObject<{
4348
+ bgColor: z.ZodOptional<z.ZodString>;
4349
+ decorations: z.ZodOptional<z.ZodBoolean>;
4350
+ bgOpacity: z.ZodOptional<z.ZodNumber>;
4351
+ footer: z.ZodOptional<z.ZodString>;
4352
+ }, z.core.$strip>>;
4353
+ layout: z.ZodLiteral<"waterfall">;
4354
+ }, z.core.$strip>;
4287
4355
  export declare const funnelStageSchema: z.ZodObject<{
4288
4356
  label: z.ZodString;
4289
4357
  value: z.ZodOptional<z.ZodString>;
@@ -6714,6 +6782,59 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6714
6782
  footer: z.ZodOptional<z.ZodString>;
6715
6783
  }, z.core.$strip>>;
6716
6784
  layout: z.ZodLiteral<"funnel">;
6785
+ }, z.core.$strip>, z.ZodObject<{
6786
+ title: z.ZodString;
6787
+ stepLabel: z.ZodOptional<z.ZodString>;
6788
+ subtitle: z.ZodOptional<z.ZodString>;
6789
+ items: z.ZodArray<z.ZodObject<{
6790
+ label: z.ZodString;
6791
+ value: z.ZodNumber;
6792
+ isTotal: z.ZodOptional<z.ZodBoolean>;
6793
+ color: z.ZodOptional<z.ZodEnum<{
6794
+ success: "success";
6795
+ primary: "primary";
6796
+ accent: "accent";
6797
+ warning: "warning";
6798
+ danger: "danger";
6799
+ info: "info";
6800
+ highlight: "highlight";
6801
+ }>>;
6802
+ }, z.core.$strip>>;
6803
+ unit: z.ZodOptional<z.ZodString>;
6804
+ callout: z.ZodOptional<z.ZodObject<{
6805
+ text: z.ZodString;
6806
+ label: z.ZodOptional<z.ZodString>;
6807
+ color: z.ZodOptional<z.ZodEnum<{
6808
+ success: "success";
6809
+ primary: "primary";
6810
+ accent: "accent";
6811
+ warning: "warning";
6812
+ danger: "danger";
6813
+ info: "info";
6814
+ highlight: "highlight";
6815
+ }>>;
6816
+ align: z.ZodOptional<z.ZodEnum<{
6817
+ left: "left";
6818
+ center: "center";
6819
+ }>>;
6820
+ leftBar: z.ZodOptional<z.ZodBoolean>;
6821
+ }, z.core.$strip>>;
6822
+ accentColor: z.ZodOptional<z.ZodEnum<{
6823
+ success: "success";
6824
+ primary: "primary";
6825
+ accent: "accent";
6826
+ warning: "warning";
6827
+ danger: "danger";
6828
+ info: "info";
6829
+ highlight: "highlight";
6830
+ }>>;
6831
+ style: z.ZodOptional<z.ZodObject<{
6832
+ bgColor: z.ZodOptional<z.ZodString>;
6833
+ decorations: z.ZodOptional<z.ZodBoolean>;
6834
+ bgOpacity: z.ZodOptional<z.ZodNumber>;
6835
+ footer: z.ZodOptional<z.ZodString>;
6836
+ }, z.core.$strip>>;
6837
+ layout: z.ZodLiteral<"waterfall">;
6717
6838
  }, z.core.$strip>], "layout">;
6718
6839
  /** Media schema registered in mulmoImageAssetSchema */
6719
6840
  export declare const mulmoSlideMediaSchema: z.ZodObject<{
@@ -9043,6 +9164,59 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
9043
9164
  footer: z.ZodOptional<z.ZodString>;
9044
9165
  }, z.core.$strip>>;
9045
9166
  layout: z.ZodLiteral<"funnel">;
9167
+ }, z.core.$strip>, z.ZodObject<{
9168
+ title: z.ZodString;
9169
+ stepLabel: z.ZodOptional<z.ZodString>;
9170
+ subtitle: z.ZodOptional<z.ZodString>;
9171
+ items: z.ZodArray<z.ZodObject<{
9172
+ label: z.ZodString;
9173
+ value: z.ZodNumber;
9174
+ isTotal: z.ZodOptional<z.ZodBoolean>;
9175
+ color: z.ZodOptional<z.ZodEnum<{
9176
+ success: "success";
9177
+ primary: "primary";
9178
+ accent: "accent";
9179
+ warning: "warning";
9180
+ danger: "danger";
9181
+ info: "info";
9182
+ highlight: "highlight";
9183
+ }>>;
9184
+ }, z.core.$strip>>;
9185
+ unit: z.ZodOptional<z.ZodString>;
9186
+ callout: z.ZodOptional<z.ZodObject<{
9187
+ text: z.ZodString;
9188
+ label: z.ZodOptional<z.ZodString>;
9189
+ color: z.ZodOptional<z.ZodEnum<{
9190
+ success: "success";
9191
+ primary: "primary";
9192
+ accent: "accent";
9193
+ warning: "warning";
9194
+ danger: "danger";
9195
+ info: "info";
9196
+ highlight: "highlight";
9197
+ }>>;
9198
+ align: z.ZodOptional<z.ZodEnum<{
9199
+ left: "left";
9200
+ center: "center";
9201
+ }>>;
9202
+ leftBar: z.ZodOptional<z.ZodBoolean>;
9203
+ }, z.core.$strip>>;
9204
+ accentColor: z.ZodOptional<z.ZodEnum<{
9205
+ success: "success";
9206
+ primary: "primary";
9207
+ accent: "accent";
9208
+ warning: "warning";
9209
+ danger: "danger";
9210
+ info: "info";
9211
+ highlight: "highlight";
9212
+ }>>;
9213
+ style: z.ZodOptional<z.ZodObject<{
9214
+ bgColor: z.ZodOptional<z.ZodString>;
9215
+ decorations: z.ZodOptional<z.ZodBoolean>;
9216
+ bgOpacity: z.ZodOptional<z.ZodNumber>;
9217
+ footer: z.ZodOptional<z.ZodString>;
9218
+ }, z.core.$strip>>;
9219
+ layout: z.ZodLiteral<"waterfall">;
9046
9220
  }, z.core.$strip>], "layout">;
9047
9221
  reference: z.ZodOptional<z.ZodString>;
9048
9222
  branding: z.ZodOptional<z.ZodNullable<z.ZodObject<{
@@ -9128,6 +9302,8 @@ export type TableCellValue = z.infer<typeof tableCellValueSchema>;
9128
9302
  export type TableSlide = z.infer<typeof tableSlideSchema>;
9129
9303
  export type FunnelStage = z.infer<typeof funnelStageSchema>;
9130
9304
  export type FunnelSlide = z.infer<typeof funnelSlideSchema>;
9305
+ export type WaterfallItem = z.infer<typeof waterfallItemSchema>;
9306
+ export type WaterfallSlide = z.infer<typeof waterfallSlideSchema>;
9131
9307
  export type SlideBrandingLogo = z.infer<typeof slideBrandingLogoSchema>;
9132
9308
  export type SlideBranding = z.infer<typeof slideBrandingSchema>;
9133
9309
  export type MulmoSlideMedia = z.infer<typeof mulmoSlideMediaSchema>;
@@ -341,6 +341,23 @@ export const tableSlideSchema = z.object({
341
341
  striped: z.boolean().optional(),
342
342
  callout: calloutBarSchema.optional(),
343
343
  });
344
+ // ─── waterfall ───
345
+ export const waterfallItemSchema = z.object({
346
+ label: z.string(),
347
+ value: z.number(),
348
+ isTotal: z.boolean().optional(),
349
+ color: accentColorKeySchema.optional(),
350
+ });
351
+ export const waterfallSlideSchema = z.object({
352
+ layout: z.literal("waterfall"),
353
+ ...slideBaseFields,
354
+ title: z.string(),
355
+ stepLabel: z.string().optional(),
356
+ subtitle: z.string().optional(),
357
+ items: z.array(waterfallItemSchema),
358
+ unit: z.string().optional(),
359
+ callout: calloutBarSchema.optional(),
360
+ });
344
361
  // ─── funnel ───
345
362
  export const funnelStageSchema = z.object({
346
363
  label: z.string(),
@@ -403,6 +420,7 @@ export const slideLayoutSchema = z.discriminatedUnion("layout", [
403
420
  matrixSlideSchema,
404
421
  tableSlideSchema,
405
422
  funnelSlideSchema,
423
+ waterfallSlideSchema,
406
424
  ]);
407
425
  /** Media schema registered in mulmoImageAssetSchema */
408
426
  export const mulmoSlideMediaSchema = z
@@ -89,6 +89,17 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
89
89
  width: number;
90
90
  height: number;
91
91
  } | undefined;
92
+ referenceImageName?: string | undefined;
93
+ referenceImage?: {
94
+ kind: "url";
95
+ url: string;
96
+ } | {
97
+ kind: "base64";
98
+ data: string;
99
+ } | {
100
+ kind: "path";
101
+ path: string;
102
+ } | undefined;
92
103
  }> | undefined;
93
104
  backgroundImage?: string | {
94
105
  source: {
@@ -263,6 +274,12 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
263
274
  })[] | undefined;
264
275
  vertexai_project?: string | undefined;
265
276
  vertexai_location?: string | undefined;
277
+ firstFrameImageName?: string | undefined;
278
+ lastFrameImageName?: string | undefined;
279
+ referenceImages?: {
280
+ imageName: string;
281
+ referenceType: "ASSET" | "STYLE";
282
+ }[] | undefined;
266
283
  };
267
284
  soundEffectParams: {
268
285
  provider?: string | undefined;
@@ -1548,6 +1565,32 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
1548
1565
  bgOpacity?: number | undefined;
1549
1566
  footer?: string | undefined;
1550
1567
  } | undefined;
1568
+ } | {
1569
+ title: string;
1570
+ items: {
1571
+ label: string;
1572
+ value: number;
1573
+ isTotal?: boolean | undefined;
1574
+ color?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
1575
+ }[];
1576
+ layout: "waterfall";
1577
+ stepLabel?: string | undefined;
1578
+ subtitle?: string | undefined;
1579
+ unit?: string | undefined;
1580
+ callout?: {
1581
+ text: string;
1582
+ label?: string | undefined;
1583
+ color?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
1584
+ align?: "left" | "center" | undefined;
1585
+ leftBar?: boolean | undefined;
1586
+ } | undefined;
1587
+ accentColor?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
1588
+ style?: {
1589
+ bgColor?: string | undefined;
1590
+ decorations?: boolean | undefined;
1591
+ bgOpacity?: number | undefined;
1592
+ footer?: string | undefined;
1593
+ } | undefined;
1551
1594
  };
1552
1595
  theme?: {
1553
1596
  colors: {
@@ -1707,6 +1750,21 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
1707
1750
  type: "chart";
1708
1751
  title: string;
1709
1752
  chartData: Record<string, any>;
1753
+ style?: string | undefined;
1754
+ backgroundImage?: string | {
1755
+ source: {
1756
+ kind: "url";
1757
+ url: string;
1758
+ } | {
1759
+ kind: "base64";
1760
+ data: string;
1761
+ } | {
1762
+ kind: "path";
1763
+ path: string;
1764
+ };
1765
+ size?: "contain" | "cover" | "fill" | "auto" | undefined;
1766
+ opacity?: number | undefined;
1767
+ } | null | undefined;
1710
1768
  } | {
1711
1769
  type: "mermaid";
1712
1770
  title: string;
@@ -1949,6 +2007,12 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
1949
2007
  })[] | undefined;
1950
2008
  vertexai_project?: string | undefined;
1951
2009
  vertexai_location?: string | undefined;
2010
+ firstFrameImageName?: string | undefined;
2011
+ lastFrameImageName?: string | undefined;
2012
+ referenceImages?: {
2013
+ imageName: string;
2014
+ referenceType: "ASSET" | "STYLE";
2015
+ }[] | undefined;
1952
2016
  speed?: number | undefined;
1953
2017
  } | undefined;
1954
2018
  soundEffectParams?: {
@@ -2019,6 +2083,17 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
2019
2083
  width: number;
2020
2084
  height: number;
2021
2085
  } | undefined;
2086
+ referenceImageName?: string | undefined;
2087
+ referenceImage?: {
2088
+ kind: "url";
2089
+ url: string;
2090
+ } | {
2091
+ kind: "base64";
2092
+ data: string;
2093
+ } | {
2094
+ kind: "path";
2095
+ path: string;
2096
+ } | undefined;
2022
2097
  }> | undefined;
2023
2098
  imageNames?: string[] | undefined;
2024
2099
  imagePrompt?: string | undefined;
@@ -2241,6 +2316,17 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
2241
2316
  width: number;
2242
2317
  height: number;
2243
2318
  } | undefined;
2319
+ referenceImageName?: string | undefined;
2320
+ referenceImage?: {
2321
+ kind: "url";
2322
+ url: string;
2323
+ } | {
2324
+ kind: "base64";
2325
+ data: string;
2326
+ } | {
2327
+ kind: "path";
2328
+ path: string;
2329
+ } | undefined;
2244
2330
  }> | undefined;
2245
2331
  backgroundImage?: string | {
2246
2332
  source: {
@@ -2415,6 +2501,12 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
2415
2501
  })[] | undefined;
2416
2502
  vertexai_project?: string | undefined;
2417
2503
  vertexai_location?: string | undefined;
2504
+ firstFrameImageName?: string | undefined;
2505
+ lastFrameImageName?: string | undefined;
2506
+ referenceImages?: {
2507
+ imageName: string;
2508
+ referenceType: "ASSET" | "STYLE";
2509
+ }[] | undefined;
2418
2510
  };
2419
2511
  soundEffectParams: {
2420
2512
  provider?: string | undefined;
@@ -3700,6 +3792,32 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
3700
3792
  bgOpacity?: number | undefined;
3701
3793
  footer?: string | undefined;
3702
3794
  } | undefined;
3795
+ } | {
3796
+ title: string;
3797
+ items: {
3798
+ label: string;
3799
+ value: number;
3800
+ isTotal?: boolean | undefined;
3801
+ color?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
3802
+ }[];
3803
+ layout: "waterfall";
3804
+ stepLabel?: string | undefined;
3805
+ subtitle?: string | undefined;
3806
+ unit?: string | undefined;
3807
+ callout?: {
3808
+ text: string;
3809
+ label?: string | undefined;
3810
+ color?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
3811
+ align?: "left" | "center" | undefined;
3812
+ leftBar?: boolean | undefined;
3813
+ } | undefined;
3814
+ accentColor?: "success" | "primary" | "accent" | "warning" | "danger" | "info" | "highlight" | undefined;
3815
+ style?: {
3816
+ bgColor?: string | undefined;
3817
+ decorations?: boolean | undefined;
3818
+ bgOpacity?: number | undefined;
3819
+ footer?: string | undefined;
3820
+ } | undefined;
3703
3821
  };
3704
3822
  theme?: {
3705
3823
  colors: {
@@ -3859,6 +3977,21 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
3859
3977
  type: "chart";
3860
3978
  title: string;
3861
3979
  chartData: Record<string, any>;
3980
+ style?: string | undefined;
3981
+ backgroundImage?: string | {
3982
+ source: {
3983
+ kind: "url";
3984
+ url: string;
3985
+ } | {
3986
+ kind: "base64";
3987
+ data: string;
3988
+ } | {
3989
+ kind: "path";
3990
+ path: string;
3991
+ };
3992
+ size?: "contain" | "cover" | "fill" | "auto" | undefined;
3993
+ opacity?: number | undefined;
3994
+ } | null | undefined;
3862
3995
  } | {
3863
3996
  type: "mermaid";
3864
3997
  title: string;
@@ -4101,6 +4234,12 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
4101
4234
  })[] | undefined;
4102
4235
  vertexai_project?: string | undefined;
4103
4236
  vertexai_location?: string | undefined;
4237
+ firstFrameImageName?: string | undefined;
4238
+ lastFrameImageName?: string | undefined;
4239
+ referenceImages?: {
4240
+ imageName: string;
4241
+ referenceType: "ASSET" | "STYLE";
4242
+ }[] | undefined;
4104
4243
  speed?: number | undefined;
4105
4244
  } | undefined;
4106
4245
  soundEffectParams?: {
@@ -4171,6 +4310,17 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
4171
4310
  width: number;
4172
4311
  height: number;
4173
4312
  } | undefined;
4313
+ referenceImageName?: string | undefined;
4314
+ referenceImage?: {
4315
+ kind: "url";
4316
+ url: string;
4317
+ } | {
4318
+ kind: "base64";
4319
+ data: string;
4320
+ } | {
4321
+ kind: "path";
4322
+ path: string;
4323
+ } | undefined;
4174
4324
  }> | undefined;
4175
4325
  imageNames?: string[] | undefined;
4176
4326
  imagePrompt?: string | undefined;
@@ -4400,6 +4550,17 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
4400
4550
  width: number;
4401
4551
  height: number;
4402
4552
  } | undefined;
4553
+ referenceImageName?: string | undefined;
4554
+ referenceImage?: {
4555
+ kind: "url";
4556
+ url: string;
4557
+ } | {
4558
+ kind: "base64";
4559
+ data: string;
4560
+ } | {
4561
+ kind: "path";
4562
+ path: string;
4563
+ } | undefined;
4403
4564
  }> | undefined;
4404
4565
  backgroundImage?: string | {
4405
4566
  source: {
@@ -4574,6 +4735,12 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
4574
4735
  })[] | undefined;
4575
4736
  vertexai_project?: string | undefined;
4576
4737
  vertexai_location?: string | undefined;
4738
+ firstFrameImageName?: string | undefined;
4739
+ lastFrameImageName?: string | undefined;
4740
+ referenceImages?: {
4741
+ imageName: string;
4742
+ referenceType: "ASSET" | "STYLE";
4743
+ }[] | undefined;
4577
4744
  };
4578
4745
  soundEffectParams: {
4579
4746
  provider?: string | undefined;
@@ -69,9 +69,9 @@ const scaleContentToFit = async (page, viewportWidth, viewportHeight) => {
69
69
  };
70
70
  /** Determine the appropriate waitUntil strategy based on HTML content */
71
71
  const resolveWaitUntil = (html) => {
72
- const hasExternalImages = html.includes("<img") && /src=["']https?:\/\//.test(html);
72
+ const hasExternalResources = (html.includes("<img") && /src=["']https?:\/\//.test(html)) || /script src=["']https?:\/\//.test(html);
73
73
  const hasLocalImages = html.includes("<img") && /src=["']file:\/\//.test(html);
74
- if (hasExternalImages)
74
+ if (hasExternalResources)
75
75
  return "networkidle0";
76
76
  if (hasLocalImages)
77
77
  return "load";
@@ -86,7 +86,8 @@ const resolveWaitUntil = (html) => {
86
86
  const loadHtmlIntoPage = async (page, html, timeout_ms) => {
87
87
  const waitUntil = resolveWaitUntil(html);
88
88
  const hasFileUrls = /file:\/\//.test(html);
89
- if (hasFileUrls) {
89
+ const hasExternalScripts = /script src=["']https?:\/\//.test(html);
90
+ if (hasFileUrls || hasExternalScripts) {
90
91
  const tmpFile = nodePath.join(os.tmpdir(), `mulmocast_render_${crypto.randomUUID()}.html`);
91
92
  fs.writeFileSync(tmpFile, html);
92
93
  try {
@@ -1,22 +1,35 @@
1
1
  import { getHTMLFile } from "../file.js";
2
2
  import { renderHTMLToImage, interpolate } from "../html_render.js";
3
3
  import { parrotingImagePath, generateUniqueId } from "./utils.js";
4
+ import { resolveCombinedStyle } from "./bg_image_util.js";
4
5
  export const imageType = "chart";
6
+ /** Chart.js plugin CDN URLs keyed by chart type */
7
+ const CHART_PLUGIN_CDNS = {
8
+ sankey: "https://cdn.jsdelivr.net/npm/chartjs-chart-sankey",
9
+ treemap: "https://cdn.jsdelivr.net/npm/chartjs-chart-treemap@3",
10
+ };
11
+ /** Resolve CDN script tags for Chart.js plugins based on chart type */
12
+ const resolveChartPlugins = (chartType) => {
13
+ const cdn = CHART_PLUGIN_CDNS[chartType];
14
+ if (!cdn)
15
+ return "";
16
+ return `<script src="${cdn}"></script>`;
17
+ };
5
18
  const processChart = async (params) => {
6
- const { beat, imagePath, canvasSize, textSlideStyle } = params;
19
+ const { beat, imagePath, canvasSize } = params;
7
20
  if (!beat.image || beat.image.type !== imageType)
8
21
  return;
9
- const isCircular = beat.image.chartData.type === "pie" ||
10
- beat.image.chartData.type === "doughnut" ||
11
- beat.image.chartData.type === "polarArea" ||
12
- beat.image.chartData.type === "radar";
22
+ const chartType = beat.image.chartData.type;
23
+ const isCircular = chartType === "pie" || chartType === "doughnut" || chartType === "polarArea" || chartType === "radar";
13
24
  const chart_width = isCircular ? Math.min(canvasSize.width, canvasSize.height) * 0.75 : canvasSize.width * 0.75;
25
+ const combinedStyle = await resolveCombinedStyle(params, beat.image.backgroundImage, beat.image.style);
14
26
  const template = getHTMLFile("chart");
15
27
  const htmlData = interpolate(template, {
16
28
  title: beat.image.title,
17
- style: textSlideStyle,
29
+ style: combinedStyle,
18
30
  chart_width: chart_width.toString(),
19
31
  chart_data: JSON.stringify(beat.image.chartData),
32
+ chart_plugins: resolveChartPlugins(chartType),
20
33
  });
21
34
  await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
22
35
  return imagePath;
@@ -3,6 +3,7 @@ import { getHTMLFile } from "../file.js";
3
3
  import { renderHTMLToImage, interpolate } from "../html_render.js";
4
4
  import { parrotingImagePath, generateUniqueId } from "./utils.js";
5
5
  import { resolveCombinedStyle } from "./bg_image_util.js";
6
+ import { resolveImageRefs, resolveMovieRefs, resolveRelativeImagePaths } from "./html_tailwind.js";
6
7
  export const imageType = "mermaid";
7
8
  // Generate mermaid HTML from code string (shared utility)
8
9
  export const generateMermaidHtml = (code, title) => {
@@ -26,11 +27,14 @@ const processMermaid = async (params) => {
26
27
  const diagram_code = await MulmoMediaSourceMethods.getText(beat.image.code, context);
27
28
  if (diagram_code) {
28
29
  const combinedStyle = await resolveCombinedStyle(params, beat.image.backgroundImage, beat.image.style);
29
- const htmlData = interpolate(template, {
30
+ const rawHtml = interpolate(template, {
30
31
  title: beat.image.title,
31
32
  style: combinedStyle,
32
33
  diagram_code: `${diagram_code}\n${beat.image.appendix?.join("\n") ?? ""}`,
33
34
  });
35
+ const resolvedImageRefs = resolveImageRefs(rawHtml, params.imageRefs ?? {});
36
+ const resolvedAllRefs = resolveMovieRefs(resolvedImageRefs, params.movieRefs ?? {});
37
+ const htmlData = resolveRelativeImagePaths(resolvedAllRefs, context.fileDirs.mulmoFileDirPath);
34
38
  await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height, true);
35
39
  }
36
40
  return imagePath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mulmocast",
3
- "version": "2.6.3",
3
+ "version": "2.6.5",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "lib/index.node.js",
@@ -88,7 +88,7 @@
88
88
  "homepage": "https://github.com/receptron/mulmocast-cli#readme",
89
89
  "dependencies": {
90
90
  "@google-cloud/text-to-speech": "^6.4.0",
91
- "@google/genai": "^1.45.0",
91
+ "@google/genai": "^1.46.0",
92
92
  "@graphai/anthropic_agent": "^2.0.12",
93
93
  "@graphai/browserless_agent": "^2.0.2",
94
94
  "@graphai/gemini_agent": "^2.0.5",
@@ -108,11 +108,11 @@
108
108
  "dotenv": "^17.3.1",
109
109
  "fluent-ffmpeg": "^2.1.3",
110
110
  "graphai": "^2.0.16",
111
- "jsdom": "^29.0.0",
112
- "marked": "^17.0.4",
111
+ "jsdom": "^29.0.1",
112
+ "marked": "^17.0.5",
113
113
  "mulmocast-vision": "^1.0.9",
114
114
  "ora": "^9.3.0",
115
- "puppeteer": "^24.39.1",
115
+ "puppeteer": "^24.40.0",
116
116
  "replicate": "^1.4.0",
117
117
  "yaml": "^2.8.2",
118
118
  "yargs": "^18.0.0",
@@ -123,10 +123,10 @@
123
123
  "@receptron/test_utils": "^2.0.3",
124
124
  "@types/archiver": "^7.0.0",
125
125
  "@types/fluent-ffmpeg": "^2.1.28",
126
- "@types/jsdom": "^28.0.0",
126
+ "@types/jsdom": "^28.0.1",
127
127
  "@types/yargs": "^17.0.35",
128
128
  "cross-env": "^10.1.0",
129
- "eslint": "^10.0.3",
129
+ "eslint": "^10.1.0",
130
130
  "eslint-config-prettier": "^10.1.8",
131
131
  "eslint-plugin-prettier": "^5.5.5",
132
132
  "eslint-plugin-sonarjs": "^4.0.2",