deckjsx 0.8.2 → 0.8.3

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.
@@ -500,7 +500,8 @@ const UNSUPPORTED_FALLBACK_STRATEGIES = [
500
500
  "preserveAuthoredValueOnly",
501
501
  "preserveOpacityWithoutCompositedSubtree",
502
502
  "preserveTransformWithoutStackingContext",
503
- "sourceRectBeforeTransform"
503
+ "sourceRectBeforeTransform",
504
+ "synthesizeFallbackFrame"
504
505
  ];
505
506
  const THEME_VALUE_GROUPS = [
506
507
  "colorScheme",
@@ -565,7 +566,8 @@ const DRAWING_ELEMENT_KINDS = [
565
566
  "group",
566
567
  "image",
567
568
  "shape",
568
- "text"
569
+ "text",
570
+ "video"
569
571
  ];
570
572
  const DRAWING_VISIBILITIES = ["hidden", "visible"];
571
573
  const DRAWING_CLIP_STRATEGIES = ["intersectParentOverflow"];
@@ -677,6 +679,7 @@ const PACKAGE_PART_KINDS = [
677
679
  "slide",
678
680
  "slide-layout",
679
681
  "slide-master",
682
+ "table-styles",
680
683
  "theme",
681
684
  "view-properties"
682
685
  ];
@@ -693,6 +696,7 @@ const PACKAGE_PART_ORDER_GROUP_ORDERS = {
693
696
  slideLayoutRelationships: 71,
694
697
  viewProperties: 75,
695
698
  presentationProperties: 76,
699
+ tableStyles: 77,
696
700
  slide: 80,
697
701
  slideRelationships: 81,
698
702
  media: 90,
@@ -762,17 +766,21 @@ const CONTENT_TYPE_CORE_PROPERTIES = "application/vnd.openxmlformats-package.cor
762
766
  const CONTENT_TYPE_EXTENDED_PROPERTIES = "application/vnd.openxmlformats-officedocument.extended-properties+xml";
763
767
  const CONTENT_TYPE_VIEW_PROPERTIES = "application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml";
764
768
  const CONTENT_TYPE_PRESENTATION_PROPERTIES = "application/vnd.openxmlformats-officedocument.presentationml.presProps+xml";
769
+ const CONTENT_TYPE_TABLE_STYLES = "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml";
765
770
  const CONTENT_TYPE_NOTES_MASTER = "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml";
766
771
  const CONTENT_TYPE_NOTES_SLIDE = "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml";
767
772
  const INTERNAL_RELATIONSHIP_TARGET_KINDS = {
768
773
  coreProperties: ["document-properties"],
769
774
  extendedProperties: ["document-properties"],
770
775
  image: ["media"],
776
+ media: ["media"],
777
+ video: ["media"],
771
778
  officeDocument: ["presentation"],
772
779
  presentationProperties: ["presentation-properties"],
773
780
  slide: ["slide"],
774
781
  slideLayout: ["slide-layout"],
775
782
  slideMaster: ["slide-master"],
783
+ tableStyles: ["table-styles"],
776
784
  theme: ["theme"],
777
785
  viewProperties: ["view-properties"]
778
786
  };
@@ -781,6 +789,7 @@ const KNOWN_RELATIONSHIP_OWNER_TYPES = {
781
789
  "presentationProperties",
782
790
  "slide",
783
791
  "slideMaster",
792
+ "tableStyles",
784
793
  "theme",
785
794
  "viewProperties"
786
795
  ],
@@ -792,7 +801,9 @@ const KNOWN_RELATIONSHIP_OWNER_TYPES = {
792
801
  slide: [
793
802
  "hyperlink",
794
803
  "image",
795
- "slideLayout"
804
+ "media",
805
+ "slideLayout",
806
+ "video"
796
807
  ],
797
808
  slideLayout: ["slideMaster"],
798
809
  slideMaster: ["slideLayout", "theme"]
@@ -937,6 +948,20 @@ function mediaPayloadDiagnostic(input) {
937
948
  }]
938
949
  });
939
950
  }
951
+ function unsupportedVideoMediaDiagnostic(input) {
952
+ return diagnostic({
953
+ severity: "error",
954
+ code: "E_PROJECT_VIDEO_FORMAT_UNSUPPORTED",
955
+ title: "video format is not supported by the pptx projection",
956
+ message: "The initial pptx video compatibility target only accepts MP4 video media.",
957
+ labels: [{
958
+ path: input.path,
959
+ message: input.message
960
+ }],
961
+ notes: [input.mediaType ? `mediaType=${input.mediaType}` : void 0, input.extension ? `extension=${input.extension}` : void 0].filter((note) => note !== void 0),
962
+ help: ["Use video/mp4 media or an .mp4 source for the video tag."]
963
+ });
964
+ }
940
965
  function partRelationshipDiagnostic(input) {
941
966
  return diagnostic({
942
967
  severity: "error",
@@ -1318,6 +1343,29 @@ function validateEmptySupportPropertiesPayload(input) {
1318
1343
  }));
1319
1344
  return issues;
1320
1345
  }
1346
+ function validateTableStylesPayload(input) {
1347
+ const path = `projection.parts.${input.part.id}.payload`;
1348
+ const payload = input.part.payload;
1349
+ if (!isRecord(payload)) return [supportPayloadDiagnostic({
1350
+ path,
1351
+ message: "invalid table styles payload"
1352
+ })];
1353
+ const record = payload;
1354
+ const issues = [];
1355
+ if (record.kind !== "table-styles") issues.push(supportPayloadDiagnostic({
1356
+ path: `${path}.kind`,
1357
+ message: "expected table-styles payload"
1358
+ }));
1359
+ if (record.editable !== true) issues.push(supportPayloadDiagnostic({
1360
+ path: `${path}.editable`,
1361
+ message: "table styles payload must remain editable"
1362
+ }));
1363
+ if (typeof record.defaultStyleId !== "string" || record.defaultStyleId.length === 0) issues.push(supportPayloadDiagnostic({
1364
+ path: `${path}.defaultStyleId`,
1365
+ message: "table styles payload requires defaultStyleId"
1366
+ }));
1367
+ return issues;
1368
+ }
1321
1369
  function validateNotesPlaceholderPayload(input) {
1322
1370
  const path = `projection.parts.${input.part.id}.payload`;
1323
1371
  const payload = input.part.payload;
@@ -3285,6 +3333,44 @@ function validateDrawingElementPayload(input) {
3285
3333
  }));
3286
3334
  return issues;
3287
3335
  }
3336
+ if (element.kind === "video") {
3337
+ if (element.mediaPartId !== void 0 && typeof element.mediaPartId !== "string") issues.push(drawingPayloadDiagnostic({
3338
+ path: `${input.path}.mediaPartId`,
3339
+ message: "invalid media part id"
3340
+ }));
3341
+ if (element.posterMediaPartId !== void 0 && typeof element.posterMediaPartId !== "string") issues.push(drawingPayloadDiagnostic({
3342
+ path: `${input.path}.posterMediaPartId`,
3343
+ message: "invalid poster media part id"
3344
+ }));
3345
+ issues.push(...validateDrawingPayloadFrame({
3346
+ value: element.sourceFrame,
3347
+ path: `${input.path}.sourceFrame`,
3348
+ message: "invalid video source frame"
3349
+ }), ...validateDrawingImageSource({
3350
+ value: element.source,
3351
+ path: `${input.path}.source`
3352
+ }), ...element.posterSource ? validateDrawingImageSource({
3353
+ value: element.posterSource,
3354
+ path: `${input.path}.posterSource`
3355
+ }) : [], ...element.fit === "contain" || element.fit === "cover" || element.fit === "stretch" ? [] : [drawingPayloadDiagnostic({
3356
+ path: `${input.path}.fit`,
3357
+ message: "invalid video fit"
3358
+ })], ...validateDrawingObjectPosition({
3359
+ value: element.objectPosition,
3360
+ path: `${input.path}.objectPosition`
3361
+ }), ...validateOptionalDrawingTransparencyField({
3362
+ value: element.transparency,
3363
+ path: `${input.path}.transparency`,
3364
+ message: "invalid video transparency"
3365
+ }), ...element.rounding === void 0 || typeof element.rounding === "boolean" ? [] : [drawingPayloadDiagnostic({
3366
+ path: `${input.path}.rounding`,
3367
+ message: "invalid video rounding"
3368
+ })], ...validateDrawingShadow({
3369
+ value: element.shadow,
3370
+ path: `${input.path}.shadow`
3371
+ }));
3372
+ return issues;
3373
+ }
3288
3374
  if (element.kind === "shape") {
3289
3375
  if (element.shape !== "rect" && element.shape !== "ellipse" && element.shape !== "line") issues.push(drawingPayloadDiagnostic({
3290
3376
  path: `${input.path}.shape`,
@@ -3879,6 +3965,129 @@ function validateSlideImageRelationships(input) {
3879
3965
  partsById: input.partsById
3880
3966
  }));
3881
3967
  }
3968
+ if (element.kind === "video") {
3969
+ const issues = [];
3970
+ if (typeof element.mediaPartId !== "string" || element.mediaPartId.length === 0) {
3971
+ issues.push(slidePayloadDiagnostic({
3972
+ path: `${input.path}.mediaPartId`,
3973
+ message: "missing video media part id"
3974
+ }));
3975
+ return issues;
3976
+ }
3977
+ const relationshipId = isRecord(element.serialized) ? element.serialized.relationshipId : void 0;
3978
+ if (typeof relationshipId !== "string" || relationshipId.length === 0) {
3979
+ issues.push(slidePayloadDiagnostic({
3980
+ path: `${input.path}.serialized.relationshipId`,
3981
+ message: "missing video relationship id"
3982
+ }));
3983
+ return issues;
3984
+ }
3985
+ const relationship = relationshipRecords(input.slidePart).find((item) => item.id === relationshipId);
3986
+ if (!relationship) {
3987
+ issues.push(slidePayloadDiagnostic({
3988
+ path: `${input.path}.serialized.relationshipId`,
3989
+ message: `missing video relationship ${relationshipId}`
3990
+ }));
3991
+ return issues;
3992
+ }
3993
+ if (relationship.type !== "video") issues.push(slidePayloadDiagnostic({
3994
+ path: `${input.path}.serialized.relationshipId`,
3995
+ message: `relationship ${relationshipId} is not a video relationship`
3996
+ }));
3997
+ if (relationship.targetPartId !== element.mediaPartId) issues.push(slidePayloadDiagnostic({
3998
+ path: `${input.path}.mediaPartId`,
3999
+ message: `video media part id does not match relationship ${relationshipId}`
4000
+ }));
4001
+ const mediaPart = input.partsById.get(element.mediaPartId);
4002
+ if (!mediaPart) {
4003
+ issues.push(slidePayloadDiagnostic({
4004
+ path: `${input.path}.mediaPartId`,
4005
+ message: `missing media part ${element.mediaPartId}`
4006
+ }));
4007
+ return issues;
4008
+ }
4009
+ if (mediaPart.kind !== "media") issues.push(slidePayloadDiagnostic({
4010
+ path: `${input.path}.mediaPartId`,
4011
+ message: `video media part id targets ${mediaPart.kind}`
4012
+ }));
4013
+ if (relationship.targetPath && normalizedPartPath(relationship.targetPath) !== normalizedPartPath(mediaPart.path)) issues.push(slidePayloadDiagnostic({
4014
+ path: `${input.path}.serialized.relationshipId`,
4015
+ message: `video relationship ${relationshipId} target path does not match media part`
4016
+ }));
4017
+ const mediaRelationshipId = isRecord(element.serialized) ? element.serialized.mediaRelationshipId : void 0;
4018
+ if (typeof mediaRelationshipId !== "string" || mediaRelationshipId.length === 0) {
4019
+ issues.push(slidePayloadDiagnostic({
4020
+ path: `${input.path}.serialized.mediaRelationshipId`,
4021
+ message: "missing embedded media relationship id"
4022
+ }));
4023
+ return issues;
4024
+ }
4025
+ const mediaRelationship = relationshipRecords(input.slidePart).find((item) => item.id === mediaRelationshipId);
4026
+ if (!mediaRelationship) {
4027
+ issues.push(slidePayloadDiagnostic({
4028
+ path: `${input.path}.serialized.mediaRelationshipId`,
4029
+ message: `missing embedded media relationship ${mediaRelationshipId}`
4030
+ }));
4031
+ return issues;
4032
+ }
4033
+ if (mediaRelationship.type !== "media") issues.push(slidePayloadDiagnostic({
4034
+ path: `${input.path}.serialized.mediaRelationshipId`,
4035
+ message: `relationship ${mediaRelationshipId} is not an embedded media relationship`
4036
+ }));
4037
+ if (mediaRelationship.targetPartId !== element.mediaPartId) issues.push(slidePayloadDiagnostic({
4038
+ path: `${input.path}.mediaPartId`,
4039
+ message: `video media part id does not match embedded media relationship ${mediaRelationshipId}`
4040
+ }));
4041
+ if (!element.posterSource) {
4042
+ issues.push(slidePayloadDiagnostic({
4043
+ path: `${input.path}.posterSource`,
4044
+ message: "missing video poster source"
4045
+ }));
4046
+ return issues;
4047
+ }
4048
+ if (typeof element.posterMediaPartId !== "string" || element.posterMediaPartId.length === 0) {
4049
+ issues.push(slidePayloadDiagnostic({
4050
+ path: `${input.path}.posterMediaPartId`,
4051
+ message: "missing video poster media part id"
4052
+ }));
4053
+ return issues;
4054
+ }
4055
+ const posterPart = input.partsById.get(element.posterMediaPartId);
4056
+ if (!posterPart) {
4057
+ issues.push(slidePayloadDiagnostic({
4058
+ path: `${input.path}.posterMediaPartId`,
4059
+ message: `missing video poster media part ${element.posterMediaPartId}`
4060
+ }));
4061
+ return issues;
4062
+ }
4063
+ if (posterPart.kind !== "media") issues.push(slidePayloadDiagnostic({
4064
+ path: `${input.path}.posterMediaPartId`,
4065
+ message: `video poster media part id targets ${posterPart.kind}`
4066
+ }));
4067
+ const posterPayload = isRecord(posterPart.payload) ? posterPart.payload : void 0;
4068
+ if (posterPayload?.mediaKind !== void 0 && posterPayload.mediaKind !== "image") issues.push(slidePayloadDiagnostic({
4069
+ path: `${input.path}.posterMediaPartId`,
4070
+ message: "video poster media part id must target image media"
4071
+ }));
4072
+ const posterSourceKey = imageSourceKeyForValidation(element.posterSource);
4073
+ if (!(posterSourceKey ? mediaPartsBySourceKey(input.partsById).get(posterSourceKey) ?? [] : []).some((part) => part.id === element.posterMediaPartId)) issues.push(slidePayloadDiagnostic({
4074
+ path: `${input.path}.posterSource`,
4075
+ message: `video poster source does not match media part ${element.posterMediaPartId}`
4076
+ }));
4077
+ const posterRelationship = relationshipRecords(input.slidePart).find((item) => item.type === "image" && item.targetPartId === element.posterMediaPartId);
4078
+ if (!posterRelationship) {
4079
+ issues.push(slidePayloadDiagnostic({
4080
+ path: `${input.path}.posterMediaPartId`,
4081
+ message: `missing video poster image relationship to ${element.posterMediaPartId}`
4082
+ }));
4083
+ return issues;
4084
+ }
4085
+ if (posterRelationship.targetPath && normalizedPartPath(posterRelationship.targetPath) !== normalizedPartPath(posterPart.path)) issues.push(slidePayloadDiagnostic({
4086
+ path: `${input.path}.posterMediaPartId`,
4087
+ message: `video poster image relationship ${posterRelationship.id} target path does not match media part`
4088
+ }));
4089
+ return issues;
4090
+ }
3882
4091
  if (element.kind !== "image") return [];
3883
4092
  const issues = [];
3884
4093
  if (typeof element.mediaPartId !== "string" || element.mediaPartId.length === 0) {
@@ -4707,6 +4916,7 @@ function mediaContentTypeForExtension(extension) {
4707
4916
  case "png": return "image/png";
4708
4917
  case "gif": return "image/gif";
4709
4918
  case "svg": return "image/svg+xml";
4919
+ case "mp4": return "video/mp4";
4710
4920
  default: return "application/octet-stream";
4711
4921
  }
4712
4922
  }
@@ -4719,6 +4929,7 @@ function expectedOverrideContentType(part) {
4719
4929
  case "notes-slide": return CONTENT_TYPE_NOTES_SLIDE;
4720
4930
  case "presentation": return CONTENT_TYPE_PRESENTATION;
4721
4931
  case "presentation-properties": return CONTENT_TYPE_PRESENTATION_PROPERTIES;
4932
+ case "table-styles": return CONTENT_TYPE_TABLE_STYLES;
4722
4933
  case "slide": return CONTENT_TYPE_SLIDE;
4723
4934
  case "slide-layout": return CONTENT_TYPE_SLIDE_LAYOUT;
4724
4935
  case "slide-master": return CONTENT_TYPE_SLIDE_MASTER;
@@ -5040,6 +5251,15 @@ function validatePresentationRelationships(input) {
5040
5251
  type: "presentationProperties",
5041
5252
  targetPartId: candidate.id
5042
5253
  }));
5254
+ if (candidate.kind === "table-styles" && !relationshipExists(input.relationships, {
5255
+ type: "tableStyles",
5256
+ targetPartId: candidate.id
5257
+ })) issues.push(missingRequiredRelationshipDiagnostic({
5258
+ ownerPart: input.part,
5259
+ message: "Presentation relationships require a projected tableStyles relationship id.",
5260
+ type: "tableStyles",
5261
+ targetPartId: candidate.id
5262
+ }));
5043
5263
  });
5044
5264
  if (isPresentationPayload(input.part.payload)) input.part.payload.slidePartIds.forEach((slidePartId) => {
5045
5265
  if (!relationshipExists(input.relationships, {
@@ -5245,12 +5465,45 @@ function validatePrimarySourceInSources(input) {
5245
5465
  function mediaMetadataRecord(payload) {
5246
5466
  return isRecord(payload.metadata) ? payload.metadata : void 0;
5247
5467
  }
5468
+ function normalizedMetadataString(value) {
5469
+ return typeof value === "string" && value.length > 0 ? value.toLowerCase() : void 0;
5470
+ }
5471
+ function validateVideoMediaCompatibility(input) {
5472
+ if (input.payload.mediaKind !== "video") return [];
5473
+ const mediaType = normalizedMetadataString(input.metadata?.mediaType)?.split(";")[0]?.trim();
5474
+ const extension = normalizedMetadataString(input.metadata?.extension ?? input.pathExtension);
5475
+ const issues = [];
5476
+ if (mediaType !== void 0 && mediaType !== "video/mp4") issues.push(unsupportedVideoMediaDiagnostic({
5477
+ path: `${input.path}.metadata.mediaType`,
5478
+ message: "video media type is outside the initial pptx compatibility target",
5479
+ mediaType,
5480
+ ...extension ? { extension } : {}
5481
+ }));
5482
+ if (extension !== void 0 && extension !== "mp4") {
5483
+ const extensionPath = input.metadata?.extension !== void 0 ? `${input.path}.metadata.extension` : input.path.replace(/\.payload$/, ".path");
5484
+ issues.push(unsupportedVideoMediaDiagnostic({
5485
+ path: extensionPath,
5486
+ message: "video media extension is outside the initial pptx compatibility target",
5487
+ ...mediaType ? { mediaType } : {},
5488
+ extension
5489
+ }));
5490
+ }
5491
+ if (mediaType === void 0 && extension === void 0) issues.push(unsupportedVideoMediaDiagnostic({
5492
+ path: input.path,
5493
+ message: "video media type and extension could not be inferred"
5494
+ }));
5495
+ return issues;
5496
+ }
5248
5497
  function validateMediaPayloadConsistency(input) {
5249
5498
  const path = `projection.parts.${input.part.id}.payload`;
5250
5499
  const metadata = mediaMetadataRecord(input.payload);
5251
5500
  const issues = [];
5252
5501
  const pathExtension = packagePartExtension(input.part);
5253
5502
  const metadataExtension = metadata?.extension;
5503
+ if (input.payload.mediaKind !== void 0 && input.payload.mediaKind !== "image" && input.payload.mediaKind !== "video") issues.push(mediaPayloadDiagnostic({
5504
+ path: `${path}.mediaKind`,
5505
+ message: "invalid media kind"
5506
+ }));
5254
5507
  if (pathExtension && typeof metadataExtension === "string" && metadataExtension.toLowerCase() !== pathExtension) issues.push(mediaPayloadDiagnostic({
5255
5508
  path: `${path}.metadata.extension`,
5256
5509
  message: `media metadata extension does not match package path extension ${pathExtension}`
@@ -5264,7 +5517,7 @@ function validateMediaPayloadConsistency(input) {
5264
5517
  }
5265
5518
  if (typeof metadata?.hash === "string" && metadata.hash.length > 0) {
5266
5519
  const allocationKey = input.payload.allocationKey;
5267
- if (typeof allocationKey === "string" && allocationKey.length > 0 && !allocationKey.startsWith(`hash:${metadata.hash}:`)) issues.push(mediaPayloadDiagnostic({
5520
+ if (typeof allocationKey === "string" && allocationKey.length > 0 && !allocationKey.startsWith(`hash:${metadata.hash}:`) && !allocationKey.startsWith(`${input.payload.mediaKind ?? "image"}:hash:${metadata.hash}:`)) issues.push(mediaPayloadDiagnostic({
5268
5521
  path: `${path}.allocationKey`,
5269
5522
  message: "media allocation key does not include metadata hash"
5270
5523
  }));
@@ -5288,6 +5541,12 @@ function validateMediaPayloadConsistency(input) {
5288
5541
  values: input.payload.assetEntityIds,
5289
5542
  label: "media asset id"
5290
5543
  }));
5544
+ issues.push(...validateVideoMediaCompatibility({
5545
+ path,
5546
+ pathExtension,
5547
+ payload: input.payload,
5548
+ metadata
5549
+ }));
5291
5550
  return issues;
5292
5551
  }
5293
5552
  function validateMediaPayload(input) {
@@ -5417,7 +5676,7 @@ function isPackagePartRequirementCondition(value) {
5417
5676
  return value === "explicit" || value === "hasRelationships" || value === "minimalPackage" || value === "referencedByRelationship";
5418
5677
  }
5419
5678
  function isPackagePartOrderGroup(value) {
5420
- return value === "contentTypes" || value === "documentProperties" || value === "media" || value === "other" || value === "presentation" || value === "presentationProperties" || value === "presentationRelationships" || value === "rootRelationships" || value === "slide" || value === "slideLayout" || value === "slideLayoutRelationships" || value === "slideMaster" || value === "slideMasterRelationships" || value === "slideRelationships" || value === "theme" || value === "viewProperties";
5679
+ return value === "contentTypes" || value === "documentProperties" || value === "media" || value === "other" || value === "presentation" || value === "presentationProperties" || value === "presentationRelationships" || value === "rootRelationships" || value === "slide" || value === "slideLayout" || value === "slideLayoutRelationships" || value === "slideMaster" || value === "slideMasterRelationships" || value === "slideRelationships" || value === "tableStyles" || value === "theme" || value === "viewProperties";
5421
5680
  }
5422
5681
  function expectedPackagePartOrderGroup(part) {
5423
5682
  const path = normalizedPartPath(part.path);
@@ -5433,6 +5692,7 @@ function expectedPackagePartOrderGroup(part) {
5433
5692
  if (part.kind === "relationships" && path.startsWith("ppt/slideLayouts/_rels/")) return "slideLayoutRelationships";
5434
5693
  if (part.kind === "view-properties") return "viewProperties";
5435
5694
  if (part.kind === "presentation-properties") return "presentationProperties";
5695
+ if (part.kind === "table-styles") return "tableStyles";
5436
5696
  if (part.kind === "slide") return "slide";
5437
5697
  if (part.kind === "relationships" && path.startsWith("ppt/slides/_rels/")) return "slideRelationships";
5438
5698
  if (part.kind === "media") return "media";
@@ -5932,6 +6192,7 @@ function expectedPackagePartPathFamily(part) {
5932
6192
  case "notes-slide": return NOTES_SLIDE_PART_PATH_PATTERN.test(path) ? void 0 : "ppt/notesSlides/notesSlideN.xml";
5933
6193
  case "presentation": return path === "ppt/presentation.xml" ? void 0 : "ppt/presentation.xml";
5934
6194
  case "presentation-properties": return path === "ppt/presProps.xml" ? void 0 : "ppt/presProps.xml";
6195
+ case "table-styles": return path === "ppt/tableStyles.xml" ? void 0 : "ppt/tableStyles.xml";
5935
6196
  case "relationships": return RELATIONSHIPS_PART_PATH_PATTERNS.some((pattern) => pattern.test(path)) ? void 0 : "_rels/.rels or known ppt/*/_rels/*.xml.rels";
5936
6197
  case "slide": return SLIDE_PART_PATH_PATTERN.test(path) ? void 0 : "ppt/slides/slideN.xml";
5937
6198
  case "slide-layout": return SLIDE_LAYOUT_PART_PATH_PATTERN.test(path) ? void 0 : "ppt/slideLayouts/slideLayoutN.xml";
@@ -6280,6 +6541,7 @@ function validatePptxPackageConsistency(projection) {
6280
6541
  expectedSlideCount: presentationSlideCount
6281
6542
  }));
6282
6543
  if (part.kind === "view-properties" || part.kind === "presentation-properties") issues.push(...validateEmptySupportPropertiesPayload({ part }));
6544
+ if (part.kind === "table-styles") issues.push(...validateTableStylesPayload({ part }));
6283
6545
  if (part.kind === "notes-master" || part.kind === "notes-slide") issues.push(...validateNotesPlaceholderPayload({ part }));
6284
6546
  if (part.kind === "theme" && isThemePayload(part.payload)) issues.push(...validateThemePayload({
6285
6547
  part,
@@ -6582,6 +6844,7 @@ const PPTX_EMITTER_FINGERPRINTS = {
6582
6844
  slide: "deckjsx:pptx-emitter:slide:0.8-generated-strokes",
6583
6845
  "slide-layout": "deckjsx:pptx-emitter:slide-layout:0.8-chunk-skeleton",
6584
6846
  "slide-master": "deckjsx:pptx-emitter:slide-master:0.8-chunk-skeleton",
6847
+ "table-styles": "deckjsx:pptx-emitter:table-styles:0.8-bootstrap",
6585
6848
  theme: "deckjsx:pptx-emitter:theme:0.8-bootstrap",
6586
6849
  "view-properties": "deckjsx:pptx-emitter:view-properties:0.8-bootstrap"
6587
6850
  };
@@ -6770,12 +7033,15 @@ const RELATIONSHIP_TYPES = {
6770
7033
  coreProperties: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
6771
7034
  extendedProperties: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
6772
7035
  image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
7036
+ media: "http://schemas.microsoft.com/office/2007/relationships/media",
7037
+ video: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video",
6773
7038
  hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
6774
7039
  officeDocument: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
6775
7040
  presentationProperties: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps",
6776
7041
  slide: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide",
6777
7042
  slideLayout: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
6778
7043
  slideMaster: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster",
7044
+ tableStyles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles",
6779
7045
  theme: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
6780
7046
  viewProperties: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps"
6781
7047
  };
@@ -6937,14 +7203,37 @@ function presentationBytes(part, projection) {
6937
7203
  })
6938
7204
  });
6939
7205
  });
6940
- return writer.close("p:sldIdLst").empty("p:sldSz", {
7206
+ writer.close("p:sldIdLst").empty("p:sldSz", {
6941
7207
  cx: emu$1(size.widthEmu, "presentation.size.widthEmu"),
6942
7208
  cy: emu$1(size.heightEmu, "presentation.size.heightEmu"),
6943
- type: "custom"
7209
+ type: size.widthEmu === 9144e3 && size.heightEmu === 5143500 ? "screen16x9" : "custom"
6944
7210
  }).empty("p:notesSz", {
6945
7211
  cx: emu$1(size.widthEmu, "presentation.size.widthEmu"),
6946
7212
  cy: emu$1(size.heightEmu, "presentation.size.heightEmu")
6947
- }).close("p:presentation").bytes();
7213
+ }).open("p:defaultTextStyle").open("a:defPPr").empty("a:defRPr").close("a:defPPr");
7214
+ for (let level = 1; level <= 9; level += 1) writer.open(`a:lvl${level}pPr`, {
7215
+ marL: (level - 1) * 457200,
7216
+ algn: "l",
7217
+ defTabSz: 914400,
7218
+ rtl: 0,
7219
+ eaLnBrk: 1,
7220
+ latinLnBrk: 0,
7221
+ hangingPunct: 1
7222
+ }).open("a:defRPr", {
7223
+ kumimoji: 1,
7224
+ sz: 1800,
7225
+ kern: 1200
7226
+ }).open("a:solidFill").empty("a:schemeClr", { val: "tx1" }).close("a:solidFill").empty("a:latin", { typeface: "+mn-lt" }).empty("a:ea", { typeface: "+mn-ea" }).empty("a:cs", { typeface: "+mn-cs" }).close("a:defRPr").close(`a:lvl${level}pPr`);
7227
+ return writer.close("p:defaultTextStyle").close("p:presentation").bytes();
7228
+ }
7229
+ function tableStylesXml(part) {
7230
+ return new TextDecoder().decode(tableStylesBytes(part));
7231
+ }
7232
+ function tableStylesBytes(part) {
7233
+ return new XmlChunkWriter().declaration().empty("a:tblStyleLst", {
7234
+ "xmlns:a": DRAWING_ML_NS$1,
7235
+ def: part.payload.defaultStyleId
7236
+ }).bytes();
6948
7237
  }
6949
7238
  function themeXml(part) {
6950
7239
  return new TextDecoder().decode(themeBytes(part));
@@ -6961,6 +7250,32 @@ function requireThemeColor(payload, key) {
6961
7250
  if (typeof value !== "string" || !PROJECTED_RGB_COLOR_PATTERN.test(value)) throw new Error(`Theme support payload must include valid colorScheme.colors.${key}.`);
6962
7251
  return value;
6963
7252
  }
7253
+ function schemeFill(writer, transforms = []) {
7254
+ writer.open("a:solidFill").open("a:schemeClr", { val: "phClr" });
7255
+ transforms.forEach((transform) => {
7256
+ writer.empty(`a:${transform.name}`, { val: transform.val });
7257
+ });
7258
+ writer.close("a:schemeClr").close("a:solidFill");
7259
+ }
7260
+ function themeLineStyle(writer, width) {
7261
+ writer.open("a:ln", {
7262
+ w: width,
7263
+ cap: "flat",
7264
+ cmpd: "sng",
7265
+ algn: "ctr"
7266
+ }).open("a:solidFill").empty("a:schemeClr", { val: "phClr" }).close("a:solidFill").empty("a:prstDash", { val: "solid" }).empty("a:miter", { lim: 8e5 }).close("a:ln");
7267
+ }
7268
+ function themeEffectStyle(writer, shadow) {
7269
+ writer.open("a:effectStyle").open("a:effectLst");
7270
+ if (shadow) writer.open("a:outerShdw", {
7271
+ blurRad: 57150,
7272
+ dist: 19050,
7273
+ dir: 54e5,
7274
+ algn: "ctr",
7275
+ rotWithShape: 0
7276
+ }).open("a:srgbClr", { val: "000000" }).empty("a:alpha", { val: 63e3 }).close("a:srgbClr").close("a:outerShdw");
7277
+ writer.close("a:effectLst").close("a:effectStyle");
7278
+ }
6964
7279
  function themeBytes(part) {
6965
7280
  const payload = part.payload;
6966
7281
  const writer = new XmlChunkWriter().declaration().open("a:theme", {
@@ -6968,7 +7283,47 @@ function themeBytes(part) {
6968
7283
  name: requireThemeText(payload.name, "name")
6969
7284
  }).open("a:themeElements").open("a:clrScheme", { name: requireThemeText(payload.colorScheme.name, "colorScheme.name") });
6970
7285
  for (const name of THEME_COLOR_KEYS) themeColor(writer, name, requireThemeColor(payload, name));
6971
- return writer.close("a:clrScheme").open("a:fontScheme", { name: requireThemeText(payload.fontScheme.name, "fontScheme.name") }).open("a:majorFont").empty("a:latin", { typeface: requireThemeText(payload.fontScheme.majorLatin, "fontScheme.majorLatin") }).close("a:majorFont").open("a:minorFont").empty("a:latin", { typeface: requireThemeText(payload.fontScheme.minorLatin, "fontScheme.minorLatin") }).close("a:minorFont").close("a:fontScheme").open("a:fmtScheme", { name: requireThemeText(payload.formatScheme.name, "formatScheme.name") }).open("a:fillStyleLst").open("a:solidFill").empty("a:schemeClr", { val: "phClr" }).close("a:solidFill").close("a:fillStyleLst").open("a:lnStyleLst").open("a:ln", { w: 9525 }).open("a:solidFill").empty("a:schemeClr", { val: "phClr" }).close("a:solidFill").close("a:ln").close("a:lnStyleLst").open("a:effectStyleLst").open("a:effectStyle").empty("a:effectLst").close("a:effectStyle").close("a:effectStyleLst").open("a:bgFillStyleLst").open("a:solidFill").empty("a:schemeClr", { val: "phClr" }).close("a:solidFill").close("a:bgFillStyleLst").close("a:fmtScheme").close("a:themeElements").empty("a:objectDefaults").empty("a:extraClrSchemeLst").close("a:theme").bytes();
7286
+ writer.close("a:clrScheme").open("a:fontScheme", { name: requireThemeText(payload.fontScheme.name, "fontScheme.name") }).open("a:majorFont").empty("a:latin", { typeface: requireThemeText(payload.fontScheme.majorLatin, "fontScheme.majorLatin") }).empty("a:ea", { typeface: "" }).empty("a:cs", { typeface: "" }).close("a:majorFont").open("a:minorFont").empty("a:latin", { typeface: requireThemeText(payload.fontScheme.minorLatin, "fontScheme.minorLatin") }).empty("a:ea", { typeface: "" }).empty("a:cs", { typeface: "" }).close("a:minorFont").close("a:fontScheme").open("a:fmtScheme", { name: requireThemeText(payload.formatScheme.name, "formatScheme.name") }).open("a:fillStyleLst");
7287
+ schemeFill(writer);
7288
+ schemeFill(writer, [{
7289
+ name: "tint",
7290
+ val: 67e3
7291
+ }, {
7292
+ name: "satMod",
7293
+ val: 105e3
7294
+ }]);
7295
+ schemeFill(writer, [{
7296
+ name: "shade",
7297
+ val: 78e3
7298
+ }, {
7299
+ name: "satMod",
7300
+ val: 12e4
7301
+ }]);
7302
+ writer.close("a:fillStyleLst").open("a:lnStyleLst");
7303
+ themeLineStyle(writer, 12700);
7304
+ themeLineStyle(writer, 19050);
7305
+ themeLineStyle(writer, 25400);
7306
+ writer.close("a:lnStyleLst").open("a:effectStyleLst");
7307
+ themeEffectStyle(writer, false);
7308
+ themeEffectStyle(writer, false);
7309
+ themeEffectStyle(writer, true);
7310
+ writer.close("a:effectStyleLst").open("a:bgFillStyleLst");
7311
+ schemeFill(writer);
7312
+ schemeFill(writer, [{
7313
+ name: "tint",
7314
+ val: 95e3
7315
+ }, {
7316
+ name: "satMod",
7317
+ val: 17e4
7318
+ }]);
7319
+ schemeFill(writer, [{
7320
+ name: "shade",
7321
+ val: 63e3
7322
+ }, {
7323
+ name: "satMod",
7324
+ val: 12e4
7325
+ }]);
7326
+ return writer.close("a:bgFillStyleLst").close("a:fmtScheme").close("a:themeElements").empty("a:objectDefaults").empty("a:extraClrSchemeLst").close("a:theme").bytes();
6972
7327
  }
6973
7328
  function emptyShapeTree(writer) {
6974
7329
  return writer.open("p:spTree").open("p:nvGrpSpPr").empty("p:cNvPr", {
@@ -7111,6 +7466,7 @@ function supportPayloadMessage(part) {
7111
7466
  case "presentation-properties": return "presentation-properties parts must carry a structured presentation-properties payload.";
7112
7467
  case "slide-layout": return "Slide layout support parts must carry a structured slide-layout payload.";
7113
7468
  case "slide-master": return "Slide master support parts must carry a structured slide-master payload.";
7469
+ case "table-styles": return "table-styles parts must carry a structured table-styles payload.";
7114
7470
  case "theme": return "Theme support parts must carry a structured theme payload.";
7115
7471
  case "view-properties": return "view-properties parts must carry a structured view-properties payload.";
7116
7472
  case "notes-master": return "notes-master support parts must carry a structured notes-master payload.";
@@ -7155,6 +7511,10 @@ function partXml(part, projection, emitters) {
7155
7511
  const supportPart = requireSupportPart(part);
7156
7512
  return supportPart.kind === "presentation-properties" ? emptyPresentationPropertiesXml(supportPart, "presentation-properties") : void 0;
7157
7513
  }
7514
+ case "table-styles": {
7515
+ const supportPart = requireSupportPart(part);
7516
+ return supportPart.kind === "table-styles" ? tableStylesXml(supportPart) : void 0;
7517
+ }
7158
7518
  case "media":
7159
7519
  case "notes-master":
7160
7520
  case "notes-slide": return;
@@ -7197,6 +7557,10 @@ function emitPartBytes(part, projection, emitters) {
7197
7557
  const supportPart = requireSupportPart(part);
7198
7558
  return supportPart.kind === "presentation-properties" ? emptyPresentationPropertiesBytes(supportPart, "presentation-properties") : void 0;
7199
7559
  }
7560
+ case "table-styles": {
7561
+ const supportPart = requireSupportPart(part);
7562
+ return supportPart.kind === "table-styles" ? tableStylesBytes(supportPart) : void 0;
7563
+ }
7200
7564
  default: {
7201
7565
  const content = partXml(part, projection, emitters);
7202
7566
  return content ? encodeXml(content) : void 0;
@@ -7462,11 +7826,14 @@ function requireProjectedRelationshipId(relationshipId, input) {
7462
7826
  if (!relationshipId) throw new Error(`${input.label} must reference projected ${input.type} relationship id.`);
7463
7827
  return relationshipId;
7464
7828
  }
7465
- function writeNonVisual(writer, kind, id, name, hyperlinkRelationshipId, hyperlinkTooltip) {
7829
+ function writerShapeObjectNumericId(id, name) {
7466
7830
  if (typeof id !== "string" || !/^[1-9]\d*$/.test(id)) throw new Error(`${name} must carry a projected positive shape object id.`);
7467
7831
  const objectId = Number.parseInt(id, 10);
7468
7832
  if (!Number.isSafeInteger(objectId) || objectId <= 0 || objectId > MAX_WRITER_SHAPE_OBJECT_ID) throw new Error(`${name} must carry a projected positive shape object id.`);
7469
- const numericId = objectId + 1;
7833
+ return objectId + 1;
7834
+ }
7835
+ function writeNonVisual(writer, kind, id, name, hyperlinkRelationshipId, hyperlinkTooltip) {
7836
+ const numericId = writerShapeObjectNumericId(id, name);
7470
7837
  if (kind === "pic") {
7471
7838
  writer.open("p:nvPicPr").open("p:cNvPr", {
7472
7839
  id: numericId,
@@ -8149,6 +8516,54 @@ function hyperlinkRelationshipIdFor(element, context) {
8149
8516
  type: "hyperlink"
8150
8517
  }) : void 0;
8151
8518
  }
8519
+ function videoShapeObjectId(element, index) {
8520
+ return writerShapeObjectNumericId(element.serialized.shapeObjectId, `Video ${index}`);
8521
+ }
8522
+ function writeVideoNonVisual(writer, element, index, videoRelationshipId, mediaRelationshipId) {
8523
+ writer.open("p:nvPicPr").open("p:cNvPr", {
8524
+ id: videoShapeObjectId(element, index),
8525
+ name: `Video ${index}`
8526
+ }).close("p:cNvPr").open("p:cNvPicPr").empty("a:picLocks", { noChangeAspect: 1 }).close("p:cNvPicPr").open("p:nvPr").empty("a:videoFile", { "r:link": videoRelationshipId }).open("p:extLst").open("p:ext", { uri: "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}" }).empty("p14:media", {
8527
+ "xmlns:p14": "http://schemas.microsoft.com/office/powerpoint/2010/main",
8528
+ "r:embed": mediaRelationshipId
8529
+ }).close("p:ext").close("p:extLst").close("p:nvPr").close("p:nvPicPr");
8530
+ }
8531
+ function writeVideoElement(writer, element, index, inheritedOpacity, context) {
8532
+ const videoRelationshipId = requireSlideRelationshipId(element.serialized.relationshipId, {
8533
+ context,
8534
+ label: `Video drawing element ${element.id}`,
8535
+ type: "video"
8536
+ });
8537
+ const mediaRelationshipId = requireSlideRelationshipId(element.serialized.mediaRelationshipId, {
8538
+ context,
8539
+ label: `Video drawing element ${element.id}`,
8540
+ type: "media"
8541
+ });
8542
+ const posterSource = element.posterSource;
8543
+ if (!posterSource) throw new Error(`Video drawing element ${element.id} requires a projected poster source.`);
8544
+ const posterRelationshipId = requireSlideRelationshipId(context.mediaRelationshipBySource.get(imageSourceKey(posterSource)), {
8545
+ context,
8546
+ label: `Video poster drawing element ${element.id}`,
8547
+ type: "image"
8548
+ });
8549
+ const transparency = alphaValue(element.transparency, combineOpacity(inheritedOpacity, element.opacity));
8550
+ writer.open("p:pic");
8551
+ writeVideoNonVisual(writer, element, index, videoRelationshipId, mediaRelationshipId);
8552
+ writer.open("p:blipFill").open("a:blip", { "r:embed": posterRelationshipId });
8553
+ if (transparency !== void 0 && transparency !== 1e5) writer.empty("a:alphaModFix", { amt: transparency });
8554
+ writer.close("a:blip");
8555
+ writeSrcRect(writer, resolveImageSrcRect({
8556
+ ...element,
8557
+ source: posterSource,
8558
+ fit: "stretch"
8559
+ }, context, "Video poster"));
8560
+ writer.close("p:blipFill");
8561
+ writer.open("p:spPr");
8562
+ writeTransform(writer, element.frame, element.rotation, element.flipH, element.flipV);
8563
+ writer.open("a:prstGeom", { prst: element.rounding ? "roundRect" : "rect" }).empty("a:avLst").close("a:prstGeom");
8564
+ writeShadow(writer, element.shadow);
8565
+ writer.close("p:spPr").close("p:pic");
8566
+ }
8152
8567
  function writeTextElement(writer, element, index, inheritedOpacity, context) {
8153
8568
  const opacity = combineOpacity(inheritedOpacity, element.opacity);
8154
8569
  const hyperlinkRelationshipId = hyperlinkRelationshipIdFor(element, context);
@@ -8255,6 +8670,9 @@ function writeDrawingElement(writer, element, index, inheritedOpacity, context)
8255
8670
  case "image":
8256
8671
  writePictureElement(writer, element, index, context, inheritedOpacity);
8257
8672
  return;
8673
+ case "video":
8674
+ writeVideoElement(writer, element, index, inheritedOpacity, context);
8675
+ return;
8258
8676
  case "shape":
8259
8677
  writeShapeElement(writer, element, index, inheritedOpacity, context);
8260
8678
  return;