pptx-angular-viewer 3.1.1 → 3.2.1

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.
@@ -7,7 +7,7 @@ import DOMPurify from 'dompurify';
7
7
  import { z } from 'zod';
8
8
  import * as mcp from 'pptx-viewer-mcp';
9
9
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
10
- import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucideChevronLeft, LucideEraser, LucideHighlighter, LucideMousePointer2, LucidePanelRight, LucidePenTool, LucideTimer, LucideArrowLeftRight, LucideCaptions, LucideCirclePause, LucideCirclePlay, LucideGrid2x2, LucideMonitor, LucideMonitorOff, LucideRotateCcw, LucideScan, LucideZoomIn, LucideZoomOut, LucideStar, LucideMoveRight, LucidePlay, LucideMousePointerClick, LucidePaintbrush, LucideClock3, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucideLayoutTemplate, LucideScissors, LucideLink, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideColumns2, LucideCheck, LucideFileDown, LucideSearch, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideHistory, LucideMessageSquarePlus, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
10
+ import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucideChevronLeft, LucideEraser, LucideHighlighter, LucideMousePointer2, LucidePanelRight, LucidePenTool, LucideTimer, LucideArrowLeftRight, LucideCaptions, LucideCirclePause, LucideCirclePlay, LucideGrid2x2, LucideMonitor, LucideMonitorOff, LucideRotateCcw, LucideScan, LucideZoomIn, LucideZoomOut, LucideSave, LucidePlay, LucidePrinter, LucideFileDown, LucideSearch, LucideStar, LucideMoveRight, LucideMousePointerClick, LucidePaintbrush, LucideClock3, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucideLayoutTemplate, LucideScissors, LucideLink, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideColumns2, LucideCheck, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideHistory, LucideMessageSquarePlus, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
11
11
  import { XMLParser } from 'fast-xml-parser';
12
12
  import JSZip from 'jszip';
13
13
  import { DomSanitizer } from '@angular/platform-browser';
@@ -17831,12 +17831,21 @@ function removeChartSeries(data, seriesIndex) {
17831
17831
  function addChartCategory(data) {
17832
17832
  return chartDataAddCategory(data, `Cat ${data.categories.length + 1}`);
17833
17833
  }
17834
- /** Remove one category, or `null` when it is the last one. */
17835
- function removeChartCategory(data, categoryIndex) {
17834
+ /**
17835
+ * Remove one category, or `null` when it is the last one.
17836
+ *
17837
+ * `followDataPoint` mirrors File > Options > Advanced > "Properties follow
17838
+ * chart data point for current workbook" (`chartPropertiesFollowDataPoint`):
17839
+ * when `true` (the default, and PowerPoint's own default), each series'
17840
+ * per-point manual formatting re-indexes along with the removed column
17841
+ * instead of staying pinned to its old numeric position. See
17842
+ * `chartDataRemoveCategory`.
17843
+ */
17844
+ function removeChartCategory(data, categoryIndex, followDataPoint = true) {
17836
17845
  if (data.categories.length <= 1 || categoryIndex < 0 || categoryIndex >= data.categories.length) {
17837
17846
  return null;
17838
17847
  }
17839
- return chartDataRemoveCategory(data, categoryIndex);
17848
+ return chartDataRemoveCategory(data, categoryIndex, followDataPoint);
17840
17849
  }
17841
17850
  /** Rename one category label. */
17842
17851
  function setChartCategoryLabel(data, categoryIndex, label) {
@@ -32536,6 +32545,7 @@ const translationsEn = {
32536
32545
  // Print
32537
32546
  'pptx.print.title': 'Print',
32538
32547
  'pptx.print.printButton': 'Print',
32548
+ 'pptx.print.preparingToPrint': 'Preparing to print…',
32539
32549
  // Export
32540
32550
  'pptx.export.processing': 'Processing…',
32541
32551
  'pptx.export.cancel': 'Cancel',
@@ -33845,6 +33855,8 @@ const translationsEn = {
33845
33855
  'pptx.security.hidePassword': 'Hide password',
33846
33856
  'pptx.security.show': 'Show',
33847
33857
  'pptx.security.hide': 'Hide',
33858
+ 'pptx.security.protectedViewTitle': 'PROTECTED VIEW',
33859
+ 'pptx.security.enableEditing': 'Enable Editing',
33848
33860
  'pptx.ribbon.slideShowOptions': 'Slide show options',
33849
33861
  'pptx.ribbon.fromBeginning': 'From Beginning',
33850
33862
  'pptx.ribbon.presenterView': 'Presenter View',
@@ -34275,8 +34287,6 @@ const translationsEn = {
34275
34287
  'pptx.file.copyImageTooltip': 'Copy Slide as Image',
34276
34288
  'pptx.file.fonts': 'Fonts',
34277
34289
  'pptx.file.gif': 'GIF',
34278
- 'pptx.file.package': 'Package',
34279
- 'pptx.file.packageTooltip': 'Package for Sharing',
34280
34290
  'pptx.file.pdf': 'PDF',
34281
34291
  'pptx.file.png': 'PNG',
34282
34292
  'pptx.file.saveAsPpsx': 'Save .ppsx',
@@ -35070,6 +35080,8 @@ const translationsEn = {
35070
35080
  'pptx.options.advanced.display': 'Display',
35071
35081
  'pptx.options.advanced.recentCount': 'Show this number of Recent Presentations',
35072
35082
  'pptx.options.advanced.disableHardwareAcceleration': 'Disable hardware graphics acceleration',
35083
+ 'pptx.options.advanced.disable3DRendering': 'Disable 3D rendering (for performance)',
35084
+ 'pptx.options.advanced.disable3DRenderingInfo': 'Forces every 3D chart and SmartArt scene to fall back to flat 2D rendering, even in a presentation that enables 3D. Turn this on if 3D scenes run slowly on this device.',
35073
35085
  'pptx.options.advanced.openDocumentsView': 'Open all documents using this view',
35074
35086
  'pptx.options.openView.savedView': 'The view saved in the file',
35075
35087
  'pptx.options.openView.normal': 'Normal',
@@ -35379,8 +35391,6 @@ const translationsEn = {
35379
35391
  'pptx.backstage.card.saveAsPpsx.body': 'Save a .ppsx file that opens directly in slide show.',
35380
35392
  'pptx.backstage.card.saveAsPptm.title': 'Macro-Enabled Presentation',
35381
35393
  'pptx.backstage.card.saveAsPptm.body': 'Preserve VBA content in a .pptm file.',
35382
- 'pptx.backstage.card.package.title': 'Package for Sharing',
35383
- 'pptx.backstage.card.package.body': 'Bundle the presentation and linked assets.',
35384
35394
  'pptx.backstage.card.pdf.title': 'Create PDF',
35385
35395
  'pptx.backstage.card.pdf.body': 'Publish a portable document with one page per slide.',
35386
35396
  'pptx.backstage.card.png.title': 'Export current slide',
@@ -35397,8 +35407,6 @@ const translationsEn = {
35397
35407
  'pptx.backstage.card.print.body': 'Choose a printer, layout, copies, and output settings in your browser print dialog.',
35398
35408
  'pptx.backstage.card.share.title': 'Share with People',
35399
35409
  'pptx.backstage.card.share.body': 'Invite collaborators and work on the presentation together.',
35400
- 'pptx.backstage.card.sharePackage.title': 'Package for Sharing',
35401
- 'pptx.backstage.card.sharePackage.body': 'Download a self-contained package for offline sharing.',
35402
35410
  // OOXML wire tokens that controls used to render verbatim. Wording follows
35403
35411
  // PowerPoint's own dialogs; see `render/schema-label-keys.ts` for the
35404
35412
  // token -> key lookups these back.
@@ -48251,7 +48259,9 @@ function buildActiveSessionUsers(params) {
48251
48259
  const local = {
48252
48260
  id: 'local',
48253
48261
  name: params.localUserName,
48254
- initials: getUserInitials(params.localUserName),
48262
+ initials: params.localUserInitials?.trim()
48263
+ ? params.localUserInitials.trim().slice(0, 2).toUpperCase()
48264
+ : getUserInitials(params.localUserName),
48255
48265
  color: params.localUserColor ?? DEFAULT_LOCAL_COLOR,
48256
48266
  isLocal: true,
48257
48267
  }, remote = params.remoteUsers.map((user) => ({
@@ -61205,6 +61215,74 @@ function toggleBlackboard(blackout, tool) {
61205
61215
  : { blackout: 'black', tool: 'pen' };
61206
61216
  }
61207
61217
 
61218
+ /**
61219
+ * Slide-show right-click menu: shared item structure for every binding.
61220
+ *
61221
+ * PowerPoint shows a minimal Next/Previous/See All Slides/Presenter View menu
61222
+ * (plus pointer tools, blank-screen and End Presentation) when you right-click
61223
+ * during a slide show and Options > Advanced > "Show menu on right mouse
61224
+ * click" is on. React built the full menu first (`PresentationContextMenu`);
61225
+ * this module gives Vue/Angular/Svelte/Vanilla the same item order, grouping
61226
+ * and i18n keys instead of each hand-porting React's JSX structure and
61227
+ * drifting. A binding maps `getPresentationContextMenuSections` onto its own
61228
+ * menu component and wires each action id to whatever handler it already
61229
+ * uses for its toolbar's equivalent button; a capability the binding lacks
61230
+ * (e.g. no "See All Slides" grid) is simply left out of `capabilities`, and
61231
+ * the section/item is omitted rather than rendered disabled.
61232
+ */
61233
+ /**
61234
+ * Build the menu's sections for the given capabilities. Next/Previous/End
61235
+ * Presentation are always present (every binding can do those); everything
61236
+ * else is opt-in via `capabilities` so a binding missing the underlying
61237
+ * feature (e.g. Vue and Vanilla have no all-slides grid, Vue's toolbar only
61238
+ * supports a black screen) omits that item cleanly instead of rendering a
61239
+ * dead control.
61240
+ */
61241
+ function getPresentationContextMenuSections(capabilities) {
61242
+ const navItems = [
61243
+ { id: 'next', labelKey: 'pptx.presenter.nextSlide' },
61244
+ { id: 'previous', labelKey: 'pptx.presenter.previousSlide' },
61245
+ ];
61246
+ if (capabilities.seeAllSlides) {
61247
+ navItems.push({ id: 'seeAllSlides', labelKey: 'pptx.presenter.seeAllSlides' });
61248
+ }
61249
+ if (capabilities.presenterView) {
61250
+ navItems.push({ id: 'presenterView', labelKey: 'pptx.presenter.presenterView' });
61251
+ }
61252
+ const sections = [{ id: 'nav', items: navItems }];
61253
+ if (capabilities.pointerTools) {
61254
+ const pointerItems = [
61255
+ { id: 'pointerArrow', labelKey: 'pptx.presenter.pointerArrow' },
61256
+ { id: 'pointerPen', labelKey: 'pptx.presenter.pointerPen' },
61257
+ { id: 'pointerHighlighter', labelKey: 'pptx.presenter.pointerHighlighter' },
61258
+ { id: 'pointerLaser', labelKey: 'pptx.presentation.laserPointer' },
61259
+ ];
61260
+ if (capabilities.eraseInk) {
61261
+ pointerItems.push({ id: 'eraseInk', labelKey: 'pptx.presenter.eraseAllInk' });
61262
+ }
61263
+ sections.push({
61264
+ id: 'pointer',
61265
+ headingKey: 'pptx.presentation.pointerTools',
61266
+ items: pointerItems,
61267
+ });
61268
+ }
61269
+ if (capabilities.blankBlack || capabilities.blankWhite) {
61270
+ const blankItems = [];
61271
+ if (capabilities.blankBlack) {
61272
+ blankItems.push({ id: 'blankBlack', labelKey: 'pptx.presenter.blackScreen' });
61273
+ }
61274
+ if (capabilities.blankWhite) {
61275
+ blankItems.push({ id: 'blankWhite', labelKey: 'pptx.presenter.whiteScreen' });
61276
+ }
61277
+ sections.push({ id: 'screen', headingKey: 'pptx.presenter.screen', items: blankItems });
61278
+ }
61279
+ sections.push({
61280
+ id: 'end',
61281
+ items: [{ id: 'endShow', labelKey: 'pptx.presenter.endPresentation' }],
61282
+ });
61283
+ return sections;
61284
+ }
61285
+
61208
61286
  /**
61209
61287
  * The presenter view (PowerPoint's "presenter console"), described once for all
61210
61288
  * five bindings.
@@ -64855,6 +64933,11 @@ function runPresentationAction(action, options, runner) {
64855
64933
  runner.endShow();
64856
64934
  return true;
64857
64935
  case 'openUrl':
64936
+ // A declined confirmation still counts as "the click was spent on an
64937
+ // action", the same as an opened link: the show must not also advance.
64938
+ if (runner.confirmUrl && !runner.confirmUrl(intent.url)) {
64939
+ return true;
64940
+ }
64858
64941
  return safeOpenUrl(intent.url);
64859
64942
  default:
64860
64943
  return false;
@@ -70316,16 +70399,23 @@ function splitFilePath(path, translate) {
70316
70399
  * Recent autosave snapshots, newest first. `translate` only covers the two
70317
70400
  * fallback labels for a snapshot with no usable path; pass the binding's `t`
70318
70401
  * so those read in the user's language rather than English.
70402
+ *
70403
+ * @param limit File > Options > Advanced > "Quickly access this number of
70404
+ * Recent Documents" (`options.advanced.recentPresentationsCount`, 0-50).
70405
+ * Truncates the list to this many entries; `0` returns an empty list
70406
+ * (PowerPoint's own semantics for the setting). Omit to keep every stored
70407
+ * snapshot (existing callers that predate the option).
70319
70408
  */
70320
- async function listBackstageRecentFiles(translate) {
70409
+ async function listBackstageRecentFiles(translate, limit) {
70321
70410
  if (typeof indexedDB === 'undefined') {
70322
70411
  return [];
70323
70412
  }
70324
70413
  try {
70325
70414
  const snapshots = await listAutosaveSnapshots();
70326
- return snapshots
70415
+ const sorted = snapshots
70327
70416
  .map((snapshot) => ({ ...snapshot, ...splitFilePath(snapshot.key, translate) }))
70328
70417
  .sort((a, b) => b.timestamp - a.timestamp);
70418
+ return limit === undefined ? sorted : sorted.slice(0, Math.max(0, limit));
70329
70419
  }
70330
70420
  catch {
70331
70421
  return [];
@@ -70391,7 +70481,6 @@ const BACKSTAGE_CARDS = {
70391
70481
  saveAsPptx: card('saveAsPptx', 'PowerPoint Presentation', 'Save an editable .pptx copy.'),
70392
70482
  saveAsPpsx: card('saveAsPpsx', 'PowerPoint Show', 'Save a .ppsx file that opens directly in slide show.'),
70393
70483
  saveAsPptm: card('saveAsPptm', 'Macro-Enabled Presentation', 'Preserve VBA content in a .pptm file.'),
70394
- package: card('package', 'Package for Sharing', 'Bundle the presentation and linked assets.'),
70395
70484
  pdf: card('pdf', 'Create PDF', 'Publish a portable document with one page per slide.'),
70396
70485
  png: card('png', 'Export current slide', 'Create a high-quality PNG image.'),
70397
70486
  video: card('video', 'Create a Video', 'Export slide timings and animations as WebM.'),
@@ -70400,7 +70489,6 @@ const BACKSTAGE_CARDS = {
70400
70489
  copyImage: card('copyImage', 'Copy as Image', 'Copy the current slide to the clipboard.'),
70401
70490
  print: card('print', 'Print Presentation', 'Choose a printer, layout, copies, and output settings in your browser print dialog.'),
70402
70491
  share: card('share', 'Share with People', 'Invite collaborators and work on the presentation together.'),
70403
- sharePackage: card('sharePackage', 'Package for Sharing', 'Download a self-contained package for offline sharing.'),
70404
70492
  };
70405
70493
  /**
70406
70494
  * Which cards a backstage page shows, in order.
@@ -70412,10 +70500,10 @@ const BACKSTAGE_CARDS = {
70412
70500
  */
70413
70501
  const BACKSTAGE_PAGE_CARDS = {
70414
70502
  info: ['protect', 'inspect', 'embedFonts', 'signatures', 'versionHistory'],
70415
- saveAs: ['saveAsPptx', 'saveAsPpsx', 'saveAsPptm', 'package'],
70503
+ saveAs: ['saveAsPptx', 'saveAsPpsx', 'saveAsPptm'],
70416
70504
  export: ['pdf', 'png', 'video', 'gif', 'json', 'copyImage'],
70417
70505
  print: ['print'],
70418
- share: ['share', 'sharePackage'],
70506
+ share: ['share'],
70419
70507
  };
70420
70508
  /** The cards for a page, already resolved to their descriptors. */
70421
70509
  function backstageCardsFor(page) {
@@ -71851,6 +71939,21 @@ function resolveViewerAddinRows(status) {
71851
71939
  active: status?.[definition.id] ?? true,
71852
71940
  }));
71853
71941
  }
71942
+ /**
71943
+ * Build an Add-ins status map from the runtime signals every binding can
71944
+ * cheaply read: Options > Advanced > "Disable 3D rendering" (gates the two
71945
+ * three.js-backed renderers) and whether a collaboration session is live.
71946
+ * The remaining catalog entries (EMF/MTX converters, locales) have no
71947
+ * runtime on/off switch, so they are left out and fall back to `active: true`
71948
+ * in {@link resolveViewerAddinRows}.
71949
+ */
71950
+ function resolveViewerAddinStatus(disable3DRendering, collaborationActive) {
71951
+ return {
71952
+ smartArt3d: !disable3DRendering,
71953
+ model3d: !disable3DRendering,
71954
+ collaboration: collaborationActive,
71955
+ };
71956
+ }
71854
71957
 
71855
71958
  const DEFAULT_VIEWER_OPTIONS = {
71856
71959
  general: {
@@ -71909,6 +72012,7 @@ const DEFAULT_VIEWER_OPTIONS = {
71909
72012
  showGrid: false,
71910
72013
  snapToGrid: false,
71911
72014
  disableHardwareAcceleration: false,
72015
+ disable3DRendering: false,
71912
72016
  openDocumentsView: 'savedView',
71913
72017
  slideShowShowMenuOnRightClick: true,
71914
72018
  slideShowShowPopupToolbar: true,
@@ -72092,6 +72196,7 @@ function resolveDefaultPrintSettings(options) {
72092
72196
  printWhat: options.advanced.printWhat,
72093
72197
  colorMode: options.advanced.printColorMode,
72094
72198
  frameSlides: options.advanced.printFrameSlides,
72199
+ scaleToFit: options.advanced.printScaleToFit,
72095
72200
  };
72096
72201
  }
72097
72202
  /** Target raster density in ppi for image export; `undefined` = lossless/high fidelity. */
@@ -72128,6 +72233,31 @@ function shouldConfirmExternalHyperlink(options, href) {
72128
72233
  }
72129
72234
  return /^https?:/i.test(href);
72130
72235
  }
72236
+ /**
72237
+ * AND every host-supplied 3D opt-in flag with the viewer user's own
72238
+ * Options > Advanced > "Disable 3D rendering" override.
72239
+ *
72240
+ * The host prop says "this deck may render its 3D scenes"; a viewer user on
72241
+ * underpowered hardware needs a way to fall back to the flat 2D rendering
72242
+ * regardless of what the host wired up. Each binding should pass its raw
72243
+ * host props through this before feeding them to the SmartArt3D/*Chart3D
72244
+ * context/provider/service that actually gates the WebGL scenes, so the
72245
+ * override reaches every one of them uniformly instead of being wired (or
72246
+ * missed) six separate times.
72247
+ */
72248
+ function resolve3DRenderingFlags(hostFlags, options) {
72249
+ if (!options.advanced.disable3DRendering) {
72250
+ return hostFlags;
72251
+ }
72252
+ return {
72253
+ smartArt3D: false,
72254
+ surfaceChart3D: false,
72255
+ barChart3D: false,
72256
+ lineChart3D: false,
72257
+ areaChart3D: false,
72258
+ pieChart3D: false,
72259
+ };
72260
+ }
72131
72261
  /** CSS class list for the viewer root reflecting display-affecting options. */
72132
72262
  function resolveOptionRootClasses(options, prefix) {
72133
72263
  const classes = [];
@@ -72142,6 +72272,37 @@ function resolveOptionRootClasses(options, prefix) {
72142
72272
  }
72143
72273
  return classes;
72144
72274
  }
72275
+ /**
72276
+ * Whether a successful, explicit save should discard the AutoRecover
72277
+ * snapshot for the deck just saved.
72278
+ *
72279
+ * PowerPoint's default behavior: once the user has saved, the snapshot that
72280
+ * existed to recover unsaved work is stale (the file on disk already has it),
72281
+ * so it is dropped. Options > Save > "Keep the last autosaved version if I
72282
+ * close without saving" flips that off: the snapshot survives a successful
72283
+ * save too, in case the user wants to roll back to it later.
72284
+ */
72285
+ function shouldDiscardAutosaveOnSuccessfulSave(options) {
72286
+ return !options.save.keepLastAutoRecoveredVersion;
72287
+ }
72288
+ /** Whether Options > Save > "clear cache on close" should wipe recovery snapshots for this deck. */
72289
+ function shouldClearAutosaveCacheOnClose(options) {
72290
+ return options.save.clearCacheOnClose;
72291
+ }
72292
+ /**
72293
+ * Snapshot keys older than Options > Save > "cache retention" (days), for
72294
+ * periodic pruning. A non-positive or non-finite retention value prunes
72295
+ * nothing rather than everything, since it means the option could not be
72296
+ * read rather than "retain 0 days".
72297
+ */
72298
+ function resolveExpiredAutosaveSnapshots(snapshots, options, now = Date.now()) {
72299
+ const days = options.save.cacheRetentionDays;
72300
+ if (!Number.isFinite(days) || days <= 0) {
72301
+ return [];
72302
+ }
72303
+ const maxAgeMs = days * 24 * 60 * 60 * 1000;
72304
+ return snapshots.filter((snapshot) => now - snapshot.timestamp > maxAgeMs).map((s) => s.key);
72305
+ }
72145
72306
  /** Play the Accessibility > "feedback with sound" cue for a completed action. */
72146
72307
  function playFeedbackSound(options) {
72147
72308
  if (!options.accessibility.feedbackWithSound || typeof window === 'undefined') {
@@ -72260,6 +72421,9 @@ const ADVANCED_TAB = {
72260
72421
  toggle('advanced', 'showGrid', 'pptx.settings.showGrid'),
72261
72422
  toggle('advanced', 'snapToGrid', 'pptx.settings.snapToGrid'),
72262
72423
  toggle('advanced', 'disableHardwareAcceleration', 'pptx.options.advanced.disableHardwareAcceleration'),
72424
+ toggle('advanced', 'disable3DRendering', 'pptx.options.advanced.disable3DRendering', {
72425
+ infoKey: 'pptx.options.advanced.disable3DRenderingInfo',
72426
+ }),
72263
72427
  select('advanced', 'openDocumentsView', 'pptx.options.advanced.openDocumentsView', choices('pptx.options.openView', [
72264
72428
  'savedView',
72265
72429
  'normal',
@@ -72922,24 +73086,6 @@ function canvasToJpegData(canvas, quality = 0.92) {
72922
73086
  return { bytes, w: canvas.width, h: canvas.height };
72923
73087
  }
72924
73088
 
72925
- /** Build the README bundled with a presentation package-for-sharing archive. */
72926
- function generatePackageReadme(presentationFilename) {
72927
- return [
72928
- 'Presentation Package',
72929
- '====================',
72930
- '',
72931
- `This folder contains the presentation "${presentationFilename}" along with`,
72932
- 'all linked media files (images, audio, video) in the /media subfolder.',
72933
- '',
72934
- 'To view this presentation:',
72935
- '1. Open the presentation file with any compatible presentation software',
72936
- '2. Ensure the /media folder remains alongside the presentation file',
72937
- '',
72938
- `Packaged on ${new Date().toLocaleDateString()}`,
72939
- '',
72940
- ].join('\n');
72941
- }
72942
-
72943
73089
  /**
72944
73090
  * Minimal GIF89a encoder (pure JS, no external dependency) plus pure
72945
73091
  * frame-planning helpers — shared by the React, Vue, and Angular bindings.
@@ -73757,9 +73903,15 @@ function buildPrintStyleSheet(width, height, customCss) {
73757
73903
  * @param height Slide height in pixels.
73758
73904
  */
73759
73905
  function buildPrintDocument(svgs, width, height, options = {}) {
73760
- const { title = 'Print', orientation = 'landscape', colorFilter = '' } = options;
73906
+ const { title = 'Print', orientation = 'landscape', colorFilter = '', scaleToFit = true, } = options;
73761
73907
  const safeOrientation = sanitizeOrientation$1(orientation);
73762
73908
  const safeColorFilter = sanitizeCssDeclaration(colorFilter);
73909
+ // Options > Advanced > "Print scale to fit" off: render each slide SVG at
73910
+ // its native `width`/`height` instead of shrinking/growing it to fill the
73911
+ // page, matching PowerPoint's "Scale to Fit Paper" off.
73912
+ const svgSizeStyle = scaleToFit
73913
+ ? '.print-slide-page svg { max-width: 100%; max-height: 100%; width: auto; height: auto; }'
73914
+ : `.print-slide-page svg { max-width: none; max-height: none; width: ${width}px; height: ${height}px; }`;
73763
73915
  const slidePages = svgs
73764
73916
  .map((svg, i) => {
73765
73917
  // Belt-and-suspenders: the structural allow/deny-list guard runs
@@ -73797,12 +73949,7 @@ function buildPrintDocument(svgs, width, height, options = {}) {
73797
73949
  .print-slide-page:last-child {
73798
73950
  page-break-after: auto;
73799
73951
  }
73800
- .print-slide-page svg {
73801
- max-width: 100%;
73802
- max-height: 100%;
73803
- width: auto;
73804
- height: auto;
73805
- }
73952
+ ${svgSizeStyle}
73806
73953
  @page {
73807
73954
  size: ${safeOrientation};
73808
73955
  margin: 5mm;
@@ -74978,6 +75125,7 @@ const DEFAULT_PRINT_SETTINGS = {
74978
75125
  slideRange: 'all',
74979
75126
  customRangeFrom: 1,
74980
75127
  customRangeTo: 1,
75128
+ scaleToFit: true,
74981
75129
  };
74982
75130
  /** Number of ruled note lines drawn next to each slide in 3-per-page handouts. */
74983
75131
  const NOTE_LINE_COUNT = 8;
@@ -75027,6 +75175,7 @@ function validatePrintSettings(partial, slideCount) {
75027
75175
  slideRange: merged.slideRange,
75028
75176
  customRangeFrom: from,
75029
75177
  customRangeTo: to,
75178
+ scaleToFit: merged.scaleToFit ?? true,
75030
75179
  };
75031
75180
  }
75032
75181
  /**
@@ -75057,6 +75206,24 @@ function computeSlideIndices(slideRange, activeSlideIndex, slideCount, customRan
75057
75206
  }
75058
75207
  return Array.from({ length: slideCount }, (_, i) => i);
75059
75208
  }
75209
+ /**
75210
+ * Filter hidden slides out of a resolved index list, unless `includeHidden` is
75211
+ * set. Mirrors PowerPoint: slides marked "hidden" (skipped during normal
75212
+ * presentation) are excluded from print output by default too (Options >
75213
+ * Advanced > "Print hidden slides" turns that off).
75214
+ *
75215
+ * A post-filter over {@link computeSlideIndices}'s output rather than a new
75216
+ * parameter on that function: `computeSlideIndices` is called from every
75217
+ * binding's print path already and only ever received a `slideCount`, so
75218
+ * threading the slides array (or a hidden-flags array) through its signature
75219
+ * would be a breaking change to a widely-called function for one option.
75220
+ */
75221
+ function filterHiddenSlideIndices(indices, slides, includeHidden) {
75222
+ if (includeHidden) {
75223
+ return indices;
75224
+ }
75225
+ return indices.filter((index) => !slides[index]?.hidden);
75226
+ }
75060
75227
  /**
75061
75228
  * Number of slides selected by the given range. Custom ranges use 1-based,
75062
75229
  * inclusive `from`/`to` clamped to `[1, slideCount]`; an inverted range
@@ -75291,6 +75458,14 @@ function buildPrintHtmlDocument(options) {
75291
75458
  const frameStyle = frameSlides
75292
75459
  ? 'img.slide-img, .notes-slide, .handout-cell img { border: 2px solid #000 !important; }'
75293
75460
  : '';
75461
+ // Options > Advanced > "Print scale to fit" (also the Print dialog's own
75462
+ // setting when it exposes one). `false` drops the shrink/grow-to-fill
75463
+ // rules so each slide image prints at its native size instead: it may
75464
+ // overflow its page/cell (clipped by `.handout-cell`'s `overflow: hidden`)
75465
+ // or under-fill it, exactly like PowerPoint with "Scale to Fit Paper" off.
75466
+ const scaleToFitStyle = options.scaleToFit === false
75467
+ ? '.slide-page img.slide-img { max-width: none; max-height: none; width: auto; height: auto; } .handout-cell img { width: auto; height: auto; max-width: none; max-height: none; object-fit: none; }'
75468
+ : '';
75294
75469
  return `<!doctype html>
75295
75470
  <html>
75296
75471
  <head>
@@ -75333,12 +75508,94 @@ function buildPrintHtmlDocument(options) {
75333
75508
  img { break-inside: avoid; }
75334
75509
  }
75335
75510
  ${frameStyle}
75511
+ ${scaleToFitStyle}
75336
75512
  </style>
75337
75513
  </head>
75338
75514
  <body>${safeBodyHtml}</body>
75339
75515
  </html>`;
75340
75516
  }
75341
75517
 
75518
+ /**
75519
+ * DOM-touching print-window lifecycle, shared by every binding's raster
75520
+ * print path (`window.open`-based; the Svelte binding avoids all of this by
75521
+ * printing through a hidden iframe instead and has no need for it).
75522
+ *
75523
+ * `window.open` is only exempt from popup blocking while it runs as part of
75524
+ * the original user-gesture call stack; the instant a caller `await`s
75525
+ * anything first (rasterising slides one by one for notes/handouts), the
75526
+ * browser no longer considers the call gesture-initiated and silently blocks
75527
+ * it -- `window.open` just returns `null`, no error, no console warning. Each
75528
+ * binding's raster print path used to build its whole document before ever
75529
+ * calling `window.open`, so print silently did nothing the moment that build
75530
+ * crossed an `await`.
75531
+ *
75532
+ * The fix: open the window FIRST, synchronously, with a placeholder page,
75533
+ * then write the real document into that same window once it's ready. These
75534
+ * two functions are the whole fix; every binding's print handler just calls
75535
+ * them at the right points instead of re-implementing this dance itself.
75536
+ *
75537
+ * `window.open` is called WITHOUT `noopener`: with it, Chrome returns `null`
75538
+ * from `window.open` itself even though the tab genuinely opens (confirmed
75539
+ * live), so every caller here reads that as "popup blocked", bails out
75540
+ * having already left a stray blank tab behind, and never writes the print
75541
+ * document into it - the exact "print opens a blank tab and does nothing"
75542
+ * report this file exists to prevent. `noopener` protects against a page
75543
+ * reaching back into ITS OPENER via `window.opener` (reverse tabnabbing),
75544
+ * which only matters for a window opened to a third-party URL; this window
75545
+ * is opened blank (`''`) and filled entirely with the app's own
75546
+ * document.write() output, so there is no opener relationship worth cutting.
75547
+ */
75548
+ /**
75549
+ * Open a blank print window right now, synchronously, still inside the
75550
+ * click's call stack, with a placeholder page. Returns `null` if the popup
75551
+ * was blocked (fully disabled popups, say) -- callers should surface that to
75552
+ * the user (e.g. "allow popups for this site to print") rather than silently
75553
+ * doing nothing.
75554
+ *
75555
+ * @param preparingLabel - Host-translated "Preparing to print…" text shown
75556
+ * in the placeholder while the real document is assembled.
75557
+ */
75558
+ function openPendingPrintWindow(preparingLabel) {
75559
+ const printWindow = window.open('', '_blank');
75560
+ if (!printWindow) {
75561
+ return null;
75562
+ }
75563
+ const safeLabel = escapeHtml(preparingLabel);
75564
+ printWindow.document.open();
75565
+ printWindow.document.write(`<!doctype html><title>${safeLabel}</title><body style="font:14px system-ui;color:#666;padding:2rem">${safeLabel}</body>`);
75566
+ printWindow.document.close();
75567
+ return printWindow;
75568
+ }
75569
+ /**
75570
+ * Write the final print document into an already-open print window (from
75571
+ * {@link openPendingPrintWindow}, or opened directly for a path that never
75572
+ * awaits anything first), focus it, and trigger the print dialog.
75573
+ */
75574
+ function finishPrintWindow(printWindow, htmlDocument) {
75575
+ printWindow.document.open();
75576
+ printWindow.document.write(htmlDocument);
75577
+ printWindow.document.close();
75578
+ printWindow.focus();
75579
+ setTimeout(() => {
75580
+ printWindow.print();
75581
+ }, 300);
75582
+ }
75583
+ /**
75584
+ * Open a print window and write a complete document into it in one
75585
+ * synchronous call. Only safe for a path that never `await`s before this
75586
+ * point (outline; direct SVG slides) -- one that does needs the
75587
+ * `openPendingPrintWindow`/`finishPrintWindow` split instead, called before
75588
+ * and after its `await`s respectively.
75589
+ */
75590
+ function openPrintWindow(htmlDocument) {
75591
+ const printWindow = window.open('', '_blank');
75592
+ if (!printWindow) {
75593
+ return false;
75594
+ }
75595
+ finishPrintWindow(printWindow, htmlDocument);
75596
+ return true;
75597
+ }
75598
+
75342
75599
  /**
75343
75600
  * Pure video (WebM) export planning helpers shared by every binding's video
75344
75601
  * export. Frame-segment timing, fps -> frame-interval maths, and MediaRecorder
@@ -77408,7 +77665,7 @@ function createLocalStorageBackend(namespace) {
77408
77665
  /** Try IndexedDB first; fall back to localStorage on any failure. */
77409
77666
  async function resolveBackend(dbName, namespace) {
77410
77667
  try {
77411
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-wYHiLJrb.mjs');
77668
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DTLrxc9s.mjs');
77412
77669
  const db = await openChatDb(dbName);
77413
77670
  return createIdbBackend(db);
77414
77671
  }
@@ -81615,6 +81872,164 @@ function createEditorSectionOperations(host) {
81615
81872
  * unchanged.
81616
81873
  */
81617
81874
 
81875
+ /**
81876
+ * viewer-options.service.ts: signal-based owner of the File > Options store for
81877
+ * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
81878
+ *
81879
+ * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
81880
+ * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
81881
+ * Angular signal, and bundles the option-to-behavior helpers the rest of the
81882
+ * viewer consumes: history depth, autosave cadence, print defaults, screen
81883
+ * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
81884
+ * protected view, and the Options > Save cache purge.
81885
+ *
81886
+ * Deliberately constructible with plain `new` (no required injection context)
81887
+ * so the colocated unit tests can exercise it without TestBed, matching
81888
+ * {@link EditorStateService}'s optional-inject pattern.
81889
+ */
81890
+ class ViewerOptionsService {
81891
+ constructor() {
81892
+ /**
81893
+ * Optional: `inject()` needs an active injection context, which plain
81894
+ * `new ViewerOptionsService()` (used by the colocated unit tests) does not
81895
+ * provide. Outside DI the subscription simply lives as long as the instance.
81896
+ */
81897
+ this.destroyRef = (() => {
81898
+ try {
81899
+ return inject(DestroyRef);
81900
+ }
81901
+ catch {
81902
+ return null;
81903
+ }
81904
+ })();
81905
+ this.translate = (() => {
81906
+ try {
81907
+ return inject(TranslateService);
81908
+ }
81909
+ catch {
81910
+ return null;
81911
+ }
81912
+ })();
81913
+ /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
81914
+ this.store = createViewerOptionsStore();
81915
+ this._options = signal(this.store.getOptions(), /* @ts-ignore */
81916
+ ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
81917
+ /** Reactive File > Options snapshot; a new object per change. */
81918
+ this.options = this._options.asReadonly();
81919
+ const unsubscribe = this.store.subscribe((next) => this._options.set(next));
81920
+ this.destroyRef?.onDestroy(unsubscribe);
81921
+ }
81922
+ // ── Store mutations ─────────────────────────────────────────────────────
81923
+ setValue(group, key, value) {
81924
+ this.store.setValue(group, key, value);
81925
+ }
81926
+ setRibbonTabHidden(tabId, hidden) {
81927
+ this.store.setRibbonTabHidden(tabId, hidden);
81928
+ }
81929
+ setQuickAccessCommands(commandIds) {
81930
+ this.store.setQuickAccessCommands(commandIds);
81931
+ }
81932
+ reset(group) {
81933
+ this.store.reset(group);
81934
+ }
81935
+ /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
81936
+ restore(snapshot) {
81937
+ this.store.setOptions(snapshot);
81938
+ }
81939
+ // ── Behavior resolution helpers ─────────────────────────────────────────
81940
+ /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
81941
+ historyDepth() {
81942
+ return resolveHistoryDepth(this.options());
81943
+ }
81944
+ /** AutoRecover cadence in seconds for the autosave engine. */
81945
+ autosaveIntervalSeconds() {
81946
+ return resolveAutosaveIntervalSeconds(this.options());
81947
+ }
81948
+ /**
81949
+ * Raster-scale multiplier for PNG/PDF export and copy-slide-as-image.
81950
+ * Multiplied against the pre-existing 2x baseline (not used outright) so
81951
+ * the default "High fidelity" preset (raw multiplier 1) keeps today's
81952
+ * export quality instead of silently downgrading it; the explicit ppi
81953
+ * presets still scale proportionally from that baseline. Mirrors the
81954
+ * vanilla/vue/svelte bindings.
81955
+ */
81956
+ imageExportScale() {
81957
+ return 2 * resolveImageResolutionScale(this.options());
81958
+ }
81959
+ /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
81960
+ printDefaults() {
81961
+ return resolveDefaultPrintSettings(this.options());
81962
+ }
81963
+ /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
81964
+ rootClasses() {
81965
+ return resolveOptionRootClasses(this.options(), 'pptx-ng');
81966
+ }
81967
+ /** Tooltip text under the current ScreenTip style (undefined = suppress). */
81968
+ screenTip(label, description, shortcut) {
81969
+ return resolveScreenTip(this.options(), label, description, shortcut);
81970
+ }
81971
+ /** Run the enabled AutoCorrect rules over a committed run of text. */
81972
+ autoCorrect(text) {
81973
+ return applyAutoCorrect(text, this.options().proofing);
81974
+ }
81975
+ /** Play the Accessibility "feedback with sound" cue for a completed action. */
81976
+ playFeedback() {
81977
+ playFeedbackSound(this.options());
81978
+ }
81979
+ /** Whether Trust Center forces the deck to open read-only. */
81980
+ protectedView() {
81981
+ return shouldOpenInProtectedView(this.options());
81982
+ }
81983
+ /**
81984
+ * Gate an external hyperlink activation. Returns `true` when navigation may
81985
+ * proceed (no confirmation required, or the user confirmed the prompt).
81986
+ */
81987
+ confirmExternalHyperlink(href) {
81988
+ if (!shouldConfirmExternalHyperlink(this.options(), href)) {
81989
+ return true;
81990
+ }
81991
+ if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
81992
+ return true;
81993
+ }
81994
+ const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
81995
+ 'Confirm before opening external hyperlinks';
81996
+ return window.confirm(`${label}\n\n${href}`);
81997
+ }
81998
+ /**
81999
+ * Options > Save > "Delete cached files": purge every autosave recovery
82000
+ * snapshot from the shared IndexedDB store. Resolves with the purge count.
82001
+ */
82002
+ async clearCache() {
82003
+ const snapshots = await listAutosaveSnapshots();
82004
+ await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
82005
+ return snapshots.length;
82006
+ }
82007
+ /**
82008
+ * Options > Save > "keep the last AutoRecover version": whether a
82009
+ * successful `.pptx` save should discard the AutoRecover snapshot for the
82010
+ * deck just saved (PowerPoint's default: the real file already has the
82011
+ * work, so the snapshot is stale unless the user asked to keep it).
82012
+ */
82013
+ shouldDiscardAutosaveOnSave() {
82014
+ return shouldDiscardAutosaveOnSuccessfulSave(this.options());
82015
+ }
82016
+ /** Options > Save > "clear cache on close": whether to wipe snapshots now. */
82017
+ shouldClearCacheOnClose() {
82018
+ return shouldClearAutosaveCacheOnClose(this.options());
82019
+ }
82020
+ /** Options > Save > "cache retention": prune snapshots older than N days. */
82021
+ async pruneExpiredCache() {
82022
+ const snapshots = await listAutosaveSnapshots();
82023
+ const expired = resolveExpiredAutosaveSnapshots(snapshots, this.options());
82024
+ await Promise.all(expired.map((key) => deleteAutosaveSnapshot(key)));
82025
+ }
82026
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
82027
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService }); }
82028
+ }
82029
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, decorators: [{
82030
+ type: Injectable
82031
+ }], ctorParameters: () => [] });
82032
+
81618
82033
  /**
81619
82034
  * `LoadContentService`: Angular port of the React `useLoadContent` hook and
81620
82035
  * the Vue `useLoadContent` composable.
@@ -81789,6 +82204,19 @@ class LoadContentService {
81789
82204
  this.handler = null;
81790
82205
  this.renderToken = 0;
81791
82206
  this.activeBlobUrls = [];
82207
+ /**
82208
+ * Optional: `inject()` needs an active injection context, which the
82209
+ * colocated unit tests construct this service without. Trust Center >
82210
+ * "Allow external content" reads through this when present.
82211
+ */
82212
+ this.optionsService = (() => {
82213
+ try {
82214
+ return inject(ViewerOptionsService);
82215
+ }
82216
+ catch {
82217
+ return null;
82218
+ }
82219
+ })();
81792
82220
  inject(DestroyRef).onDestroy(() => {
81793
82221
  this.renderToken++;
81794
82222
  this.revokeBlobUrls(this.activeBlobUrls);
@@ -81879,7 +82307,11 @@ class LoadContentService {
81879
82307
  const sigBuffer = buffer.slice(0);
81880
82308
  const previousHandler = this.handler;
81881
82309
  const newHandler = new PptxHandler();
81882
- const parsed = await newHandler.load(buffer);
82310
+ // Trust Center > "Allow external content": gates linked (non-embedded)
82311
+ // http(s) image URLs. Defaults to blocked when the options service is
82312
+ // unreachable (e.g. constructed outside DI in a unit test).
82313
+ const allowExternalImages = this.optionsService?.options().trust.allowExternalContent ?? false;
82314
+ const parsed = await newHandler.load(buffer, { allowExternalImages });
81883
82315
  if (token !== this.renderToken) {
81884
82316
  newHandler.dispose();
81885
82317
  return;
@@ -82313,6 +82745,13 @@ class EditorStateService {
82313
82745
  ...(ngDevMode ? [{ debugName: "hasClipboard" }] : /* istanbul ignore next */ []));
82314
82746
  this.idCounter = 0;
82315
82747
  }
82748
+ /**
82749
+ * Apply File > Options > Advanced > "Maximum number of undos" at runtime.
82750
+ * Trims the past stack immediately if the new limit is smaller.
82751
+ */
82752
+ setHistoryDepth(depth) {
82753
+ this.history.setMaxDepth(depth);
82754
+ }
82316
82755
  /**
82317
82756
  * Resolve a translation. Outside an injection context (see {@link translate})
82318
82757
  * falls back to the canonical English dictionary text, then the raw key.
@@ -93655,6 +94094,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
93655
94094
  `, styles: [".pptx-ng-zoom-interactive{cursor:pointer}.pptx-ng-zoom-interactive:focus-visible{outline:2px solid #2563eb;outline-offset:2px}\n"] }]
93656
94095
  }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], markElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "markElement", required: false }] }] } });
93657
94096
 
94097
+ /**
94098
+ * Trust Center > "Confirm before opening external hyperlinks" gate for a
94099
+ * text-run hyperlink click. `confirm` is `viewerOpts?.confirmExternalHyperlink`
94100
+ * (absent outside a `PowerPointViewerComponent` host, where a click is never
94101
+ * vetoed); returns `true` when the browser's default navigation must be
94102
+ * prevented. Exported (and pure) because this package has no TestBed.
94103
+ */
94104
+ function shouldPreventHyperlinkNavigation(confirm, href) {
94105
+ return confirm !== undefined && !confirm(href);
94106
+ }
93658
94107
  /**
93659
94108
  * ElementRendererComponent: Angular port of the React `ElementRenderer.tsx`
93660
94109
  * and the Vue `ElementRenderer.vue`.
@@ -93698,6 +94147,12 @@ class ElementRendererComponent {
93698
94147
  */
93699
94148
  this.playback = inject(AnimationPlaybackService, { optional: true });
93700
94149
  this.translate = inject(TranslateService);
94150
+ /**
94151
+ * Optional so this renderer still works outside a `PowerPointViewerComponent`
94152
+ * host (thumbnails, export): a text-run hyperlink click is then never
94153
+ * confirmed, matching the option's own default meaning ("not configured").
94154
+ */
94155
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
93701
94156
  this.smartArt3D = computed(() => this.smartArt3DService?.enabled() ?? false, /* @ts-ignore */
93702
94157
  ...(ngDevMode ? [{ debugName: "smartArt3D" }] : /* istanbul ignore next */ []));
93703
94158
  /**
@@ -94051,6 +94506,18 @@ class ElementRendererComponent {
94051
94506
  }, /* @ts-ignore */
94052
94507
  ...(ngDevMode ? [{ debugName: "placeholderLabel" }] : /* istanbul ignore next */ []));
94053
94508
  }
94509
+ /**
94510
+ * Trust Center > "Confirm before opening external hyperlinks" gate for a
94511
+ * text-run hyperlink (`<a class="pptx-ng-link">`). The anchor's own `href` /
94512
+ * `target="_blank"` still does the actual navigation; this only vetoes it
94513
+ * via `preventDefault()` when the user declines the prompt.
94514
+ */
94515
+ onHyperlinkClick(event, href) {
94516
+ const confirm = this.viewerOpts?.confirmExternalHyperlink.bind(this.viewerOpts);
94517
+ if (shouldPreventHyperlinkNavigation(confirm, href)) {
94518
+ event.preventDefault();
94519
+ }
94520
+ }
94054
94521
  /** Whole-paragraph text, for the paragraph-level build wrapper. */
94055
94522
  paragraphText(para) {
94056
94523
  return para.runs.map((run) => run.text).join('');
@@ -94060,7 +94527,7 @@ class ElementRendererComponent {
94060
94527
  return { ...(span.style ?? {}), ...textBuildSpanStyle(span) };
94061
94528
  }
94062
94529
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
94063
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
94530
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
94064
94531
  }
94065
94532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, decorators: [{
94066
94533
  type: Component,
@@ -94080,7 +94547,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
94080
94547
  ZoomRendererComponent,
94081
94548
  EquationRendererComponent,
94082
94549
  ImageRendererComponent,
94083
- ], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
94550
+ ], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
94084
94551
  }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], obstacles: [{ type: i0.Input, args: [{ isSignal: true, alias: "obstacles", required: false }] }], canvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasWidth", required: false }] }], canvasHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasHeight", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], marked: [{ type: i0.Input, args: [{ isSignal: true, alias: "marked", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], fieldContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldContext", required: false }] }], slideElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideElements", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], parentGroupFill: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentGroupFill", required: false }] }], editingElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingElementId", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }] } });
94085
94552
 
94086
94553
  /**
@@ -95023,6 +95490,8 @@ class SlideCanvasComponent {
95023
95490
  this.fieldContextSvc = inject(FieldContextService, { optional: true });
95024
95491
  this.fieldContext = computed(() => this.fieldContextSvc?.forSlide(this.slide()), /* @ts-ignore */
95025
95492
  ...(ngDevMode ? [{ debugName: "fieldContext" }] : /* istanbul ignore next */ []));
95493
+ /** Options > Proofing > AutoCorrect, applied to committed inline-edit text. */
95494
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
95026
95495
  /**
95027
95496
  * Obstacle rects (absolute slide coords) for connector A* routing: every
95028
95497
  * non-connector element with a positive footprint. Bent connectors detour
@@ -95139,7 +95608,11 @@ class SlideCanvasComponent {
95139
95608
  'padding-left': rulerOffset > 0 ? `${rulerOffset}px` : '0',
95140
95609
  position: 'relative',
95141
95610
  'box-sizing': 'content-box',
95142
- margin: '1rem auto',
95611
+ flex: 'none',
95612
+ // `margin: auto` on a flex item consumes all free space on both axes,
95613
+ // centering the slide horizontally and vertically (matching Svelte),
95614
+ // rather than only horizontally with a fixed top/bottom gap.
95615
+ margin: 'auto',
95143
95616
  };
95144
95617
  }, /* @ts-ignore */
95145
95618
  ...(ngDevMode ? [{ debugName: "wrapperStyle" }] : /* istanbul ignore next */ []));
@@ -95576,7 +96049,8 @@ class SlideCanvasComponent {
95576
96049
  // is the live, still-mounted textarea (this handler runs off its own
95577
96050
  // `blur`), so no separate DOM lookup is needed here.
95578
96051
  const height = resolveCommitTextAutoFitHeight(this.allElements(), id, editor);
95579
- this.textCommit.emit(height !== undefined ? { id, text: editor.value, height } : { id, text: editor.value });
96052
+ const text = this.viewerOpts ? this.viewerOpts.autoCorrect(editor.value) : editor.value;
96053
+ this.textCommit.emit(height !== undefined ? { id, text, height } : { id, text });
95580
96054
  }
95581
96055
  onContextMenu(event) {
95582
96056
  if (!this.editable()) {
@@ -97536,6 +98010,20 @@ function toolbarVisibility(hiddenActions) {
97536
98010
  isHidden: (id) => isActionHidden(id, hiddenActions()),
97537
98011
  };
97538
98012
  }
98013
+ /**
98014
+ * Union the host's own `hiddenActions` input with File > Options > Customize
98015
+ * Ribbon's `ribbon.hiddenTabIds`, so both reach the same filter every chrome
98016
+ * component already gates on. `ToolbarTabId` is a subtype of `ToolbarActionId`,
98017
+ * so a hidden tab id fits directly into the result.
98018
+ *
98019
+ * Without this, Customize Ribbon changed only what its own pane displayed:
98020
+ * nothing downstream (the ribbon's tab strip, the title bar, the mobile
98021
+ * toolbar/menu, the status bar) ever read `ribbon.hiddenTabIds`, so ticking a
98022
+ * tab off there left every one of them unchanged.
98023
+ */
98024
+ function mergeHiddenActions(hostHiddenActions, ribbonHiddenTabIds) {
98025
+ return [...hostHiddenActions, ...ribbonHiddenTabIds];
98026
+ }
97539
98027
 
97540
98028
  /**
97541
98029
  * mobile-toolbar.component.ts: Compact mobile top toolbar.
@@ -99235,11 +99723,13 @@ class PrintService {
99235
99723
  async print(rawSettings, slides, activeSlideIndex, captureSlide, slideSize = {
99236
99724
  width: DEFAULT_CANVAS_WIDTH,
99237
99725
  height: DEFAULT_CANVAS_HEIGHT,
99238
- }) {
99726
+ },
99727
+ /** Options > Advanced > "Print hidden slides". Defaults to PowerPoint's own default (excluded). */
99728
+ includeHiddenSlides = false) {
99239
99729
  this.closeDialog();
99240
99730
  const settings = validatePrintSettings(rawSettings, slides.length);
99241
99731
  const colorFilter = computeColorFilter(settings.colorMode);
99242
- const slideIndices = computeSlideIndices(settings.slideRange, activeSlideIndex, slides.length, settings.customRangeFrom, settings.customRangeTo);
99732
+ const slideIndices = filterHiddenSlideIndices(computeSlideIndices(settings.slideRange, activeSlideIndex, slides.length, settings.customRangeFrom, settings.customRangeTo), slides, includeHiddenSlides);
99243
99733
  if (slideIndices.length === 0) {
99244
99734
  return false;
99245
99735
  }
@@ -99252,6 +99742,7 @@ class PrintService {
99252
99742
  orientation: settings.orientation,
99253
99743
  colorFilter,
99254
99744
  frameSlides: settings.frameSlides,
99745
+ scaleToFit: settings.scaleToFit,
99255
99746
  }));
99256
99747
  }
99257
99748
  if (settings.printWhat === 'slides') {
@@ -99272,9 +99763,18 @@ class PrintService {
99272
99763
  title: this.translate.instant('pptx.sections.slides'),
99273
99764
  orientation: settings.orientation,
99274
99765
  colorFilter,
99766
+ scaleToFit: settings.scaleToFit,
99275
99767
  }));
99276
99768
  }
99277
99769
  // ── Capture the requested slides to PNG data URLs ─────────────────
99770
+ // `captureSlide` awaits per slide, so the print window has to be opened
99771
+ // NOW, before that first await, or the browser silently blocks it as a
99772
+ // popup the instant the call stack leaves the click's user gesture (see
99773
+ // `openPendingPrintWindow`, shared by every window.open-based binding).
99774
+ const pendingWindow = openPendingPrintWindow(this.translate.instant('pptx.print.preparingToPrint'));
99775
+ if (!pendingWindow) {
99776
+ return false;
99777
+ }
99278
99778
  const slideImages = [];
99279
99779
  const capturedIndices = [];
99280
99780
  for (const idx of slideIndices) {
@@ -99285,19 +99785,22 @@ class PrintService {
99285
99785
  }
99286
99786
  }
99287
99787
  if (slideImages.length === 0) {
99788
+ pendingWindow.close();
99288
99789
  return false;
99289
99790
  }
99290
99791
  if (settings.printWhat === 'notes') {
99291
- return this._open(buildPrintHtmlDocument({
99792
+ finishPrintWindow(pendingWindow, buildPrintHtmlDocument({
99292
99793
  title: this.translate.instant('pptx.print.notesPages'),
99293
99794
  bodyHtml: buildNotesHtml(slideImages, capturedIndices, slides),
99294
99795
  orientation: 'portrait',
99295
99796
  colorFilter,
99296
99797
  frameSlides: settings.frameSlides,
99798
+ scaleToFit: settings.scaleToFit,
99297
99799
  }));
99800
+ return true;
99298
99801
  }
99299
99802
  // printWhat === 'handouts'
99300
- return this._open(buildPrintHtmlDocument({
99803
+ finishPrintWindow(pendingWindow, buildPrintHtmlDocument({
99301
99804
  title: this.translate.instant('pptx.print.handoutPerPageTitle', {
99302
99805
  count: settings.slidesPerPage,
99303
99806
  }),
@@ -99305,28 +99808,22 @@ class PrintService {
99305
99808
  orientation: 'portrait',
99306
99809
  colorFilter,
99307
99810
  frameSlides: settings.frameSlides,
99811
+ scaleToFit: settings.scaleToFit,
99308
99812
  }));
99813
+ return true;
99309
99814
  }
99310
99815
  /* ---------------------------------------------------------------- */
99311
99816
  /* Internal: print-window side effects (DOM only) */
99312
99817
  /* ---------------------------------------------------------------- */
99313
99818
  /**
99314
- * Open a print window, write the document, focus, and trigger printing.
99315
- * Returns `false` if the popup was blocked.
99819
+ * Open a print window, write the document, focus, and trigger printing, all
99820
+ * in one synchronous call. Used by the outline/slides paths, which never
99821
+ * `await` before this point so the window is never at risk of being popup
99822
+ * blocked -- no need for the placeholder-then-real-document split `print`'s
99823
+ * notes/handouts branch needs (see `openPendingPrintWindow`/`finishPrintWindow`).
99316
99824
  */
99317
99825
  _open(htmlDocument) {
99318
- const printWindow = window.open('', '_blank', 'noopener,noreferrer');
99319
- if (!printWindow) {
99320
- return false;
99321
- }
99322
- printWindow.document.open();
99323
- printWindow.document.write(htmlDocument);
99324
- printWindow.document.close();
99325
- printWindow.focus();
99326
- setTimeout(() => {
99327
- printWindow.print();
99328
- }, 300);
99329
- return true;
99826
+ return openPrintWindow(htmlDocument);
99330
99827
  }
99331
99828
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
99332
99829
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintService }); }
@@ -99627,6 +100124,8 @@ class ViewerCanvasEditingService {
99627
100124
  this.dialogs = inject(ViewerDialogsService);
99628
100125
  this.formatPainter = inject(ViewerFormatPainterService);
99629
100126
  this.collab = inject(CollaborationService);
100127
+ /** Options > Proofing > AutoCorrect, applied to committed inline-edit text. */
100128
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
99630
100129
  /** Id of the element being inline text-edited, or null. */
99631
100130
  this.editingId = signal(null, /* @ts-ignore */
99632
100131
  ...(ngDevMode ? [{ debugName: "editingId" }] : /* istanbul ignore next */ []));
@@ -99812,7 +100311,10 @@ class ViewerCanvasEditingService {
99812
100311
  if (!el || el.type !== 'table') {
99813
100312
  return;
99814
100313
  }
99815
- const updated = setCellText(el, event.commit.rowIndex, event.commit.colIndex, event.commit.text);
100314
+ const text = this.viewerOpts
100315
+ ? this.viewerOpts.autoCorrect(event.commit.text)
100316
+ : event.commit.text;
100317
+ const updated = setCellText(el, event.commit.rowIndex, event.commit.colIndex, text);
99816
100318
  this.editor.updateElement(host.activeSlideIndex(), event.id, {
99817
100319
  tableData: updated.tableData,
99818
100320
  });
@@ -100035,6 +100537,7 @@ function buildShareUrl(roomId, serverUrl, location) {
100035
100537
  class ViewerCollaborationSessionService {
100036
100538
  constructor() {
100037
100539
  this.collab = inject(CollaborationService);
100540
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
100038
100541
  /** Share (collaboration) dialog visibility. */
100039
100542
  this.showShare = signal(false, /* @ts-ignore */
100040
100543
  ...(ngDevMode ? [{ debugName: "showShare" }] : /* istanbul ignore next */ []));
@@ -100074,6 +100577,7 @@ class ViewerCollaborationSessionService {
100074
100577
  }
100075
100578
  return buildActiveSessionUsers({
100076
100579
  localUserName: config.userName,
100580
+ localUserInitials: this.viewerOpts?.options().general.userInitials,
100077
100581
  localUserColor: config.userColor,
100078
100582
  remoteUsers: this.collab.presence(),
100079
100583
  });
@@ -100295,6 +100799,21 @@ function annotationMapToInkInserts(map) {
100295
100799
  }
100296
100800
  return inserts;
100297
100801
  }
100802
+ /**
100803
+ * Real runtime availability for the Options > Add-ins pane, for the catalog
100804
+ * ids this host can answer cheaply. Every other id (emfConverter,
100805
+ * mtxDecompressor, locales) has no meaningful "off" state: they are
100806
+ * compile-time bundled dependencies, always present, so they fall back to
100807
+ * `resolveViewerAddinRows`'s own `active: true` default instead of a
100808
+ * fabricated signal.
100809
+ */
100810
+ function resolveViewerExtraAddinStatus(flags) {
100811
+ return {
100812
+ smartArt3d: flags.smartArt3dEnabled,
100813
+ model3d: !flags.disable3DRendering,
100814
+ collaboration: flags.collaborationConnected,
100815
+ };
100816
+ }
100298
100817
  /**
100299
100818
  * Return a new slide array with the accepted diff applied: an `added` slide is
100300
100819
  * appended, a `changed`/`removed` slide adopts the incoming (`compareSlide`)
@@ -100329,6 +100848,7 @@ class ViewerCompareService {
100329
100848
  this.svc = inject(ViewerDialogsService);
100330
100849
  this.editor = inject(EditorStateService);
100331
100850
  this.translate = inject(TranslateService);
100851
+ this.optionsService = inject(ViewerOptionsService);
100332
100852
  }
100333
100853
  /**
100334
100854
  * Open a `.pptx` picker and diff it against the current deck, opening the
@@ -100355,7 +100875,8 @@ class ViewerCompareService {
100355
100875
  try {
100356
100876
  const buffer = await file.arrayBuffer();
100357
100877
  const handler = new PptxHandler();
100358
- const parsed = await handler.load(buffer);
100878
+ const allowExternalImages = this.optionsService.options().trust.allowExternalContent;
100879
+ const parsed = await handler.load(buffer, { allowExternalImages });
100359
100880
  const result = compareSlides([...this.editor.slides()], [...parsed.slides]);
100360
100881
  this.svc.compareResult.set(result);
100361
100882
  this.svc.showCompare.set(true);
@@ -100739,7 +101260,7 @@ class ViewerExportService {
100739
101260
  }
100740
101261
  this.exporting.set(true);
100741
101262
  try {
100742
- await this.exportSvc.exportElementToPng(el, slideFileName('slide', host.activeSlideIndex() + 1, 'png'));
101263
+ await this.exportSvc.exportElementToPng(el, slideFileName('slide', host.activeSlideIndex() + 1, 'png'), host.imageExportScale?.() ?? 2);
100743
101264
  }
100744
101265
  finally {
100745
101266
  this.exporting.set(false);
@@ -100747,13 +101268,14 @@ class ViewerExportService {
100747
101268
  }
100748
101269
  /** Copy the current slide to the system clipboard as a PNG image. */
100749
101270
  async copySlideAsImage() {
100750
- const el = this.requireHost().resolveStage();
101271
+ const host = this.requireHost();
101272
+ const el = host.resolveStage();
100751
101273
  if (!el || this.exporting()) {
100752
101274
  return;
100753
101275
  }
100754
101276
  this.exporting.set(true);
100755
101277
  try {
100756
- await this.exportSvc.copyElementAsPng(el);
101278
+ await this.exportSvc.copyElementAsPng(el, host.imageExportScale?.() ?? 2);
100757
101279
  }
100758
101280
  catch (err) {
100759
101281
  console.error('[PowerPointViewer] Copy slide as image failed:', err);
@@ -100775,7 +101297,7 @@ class ViewerExportService {
100775
101297
  const controller = this.beginExport(this.translate.instant('pptx.mobileMenu.exportPdf'));
100776
101298
  const { width, height } = this.loader.canvasSize();
100777
101299
  try {
100778
- const canvases = await this.captureSlideCanvases(controller.signal, this.translate.instant('pptx.export.rendering'), 90);
101300
+ const canvases = await this.captureSlideCanvases(controller.signal, this.translate.instant('pptx.export.rendering'), 90, this.requireHost().imageExportScale?.() ?? 2);
100779
101301
  this.progress.set(EXPORT_ASSEMBLING_PERCENT);
100780
101302
  this.statusMessage.set(this.translate.instant('pptx.export.buildingPdf'));
100781
101303
  this.exportSvc.exportCanvasesToPdf(canvases, width, height, 'presentation.pdf');
@@ -100839,11 +101361,18 @@ class ViewerExportService {
100839
101361
  this.endExport();
100840
101362
  }
100841
101363
  }
100842
- async onPrint(settings) {
101364
+ /**
101365
+ * `includeHiddenSlides`: Options > Advanced > "Print hidden slides".
101366
+ * `highQuality`: Options > Advanced > "High quality" raster scale for the
101367
+ * notes/handouts fallback path, composed on top of the host's own Image
101368
+ * Size/Quality scale.
101369
+ */
101370
+ async onPrint(settings, includeHiddenSlides = false, highQuality = false) {
100843
101371
  const host = this.requireHost();
100844
101372
  const original = host.activeSlideIndex();
101373
+ const printScale = (host.imageExportScale?.() ?? 2) * (highQuality ? 2 : 1);
100845
101374
  try {
100846
- await this.print.print(settings, [...host.mergedSlides()], original, (index) => this.captureSlideDataUrl(index), this.loader.canvasSize());
101375
+ await this.print.print(settings, [...host.mergedSlides()], original, (index) => this.captureSlideDataUrl(index, printScale), this.loader.canvasSize(), includeHiddenSlides);
100847
101376
  }
100848
101377
  finally {
100849
101378
  host.activeSlideIndex.set(original);
@@ -100878,7 +101407,7 @@ class ViewerExportService {
100878
101407
  * Render every slide to a canvas (each made the live stage in turn), reporting
100879
101408
  * per-slide progress and bailing out cooperatively when `abortSignal.aborted`.
100880
101409
  */
100881
- async captureSlideCanvases(abortSignal, verb, span) {
101410
+ async captureSlideCanvases(abortSignal, verb, span, scale = 2) {
100882
101411
  const host = this.requireHost();
100883
101412
  const total = host.slideCount();
100884
101413
  const original = host.activeSlideIndex();
@@ -100896,7 +101425,7 @@ class ViewerExportService {
100896
101425
  });
100897
101426
  const el = host.resolveStage();
100898
101427
  if (el) {
100899
- canvases.push(await this.exportSvc.renderElement(el));
101428
+ canvases.push(await this.exportSvc.renderElement(el, scale));
100900
101429
  }
100901
101430
  }
100902
101431
  }
@@ -100905,8 +101434,13 @@ class ViewerExportService {
100905
101434
  }
100906
101435
  return canvases;
100907
101436
  }
100908
- /** Flip the live stage to `index`, let it settle, and capture it to a PNG data URL. */
100909
- async captureSlideDataUrl(index) {
101437
+ /**
101438
+ * Flip the live stage to `index`, let it settle, and capture it to a PNG
101439
+ * data URL. `scale` defaults to the host's own Image Size/Quality scale
101440
+ * (matching PNG/PDF export); the print notes/handouts path passes a higher
101441
+ * value when Options > Advanced > "High quality" is on.
101442
+ */
101443
+ async captureSlideDataUrl(index, scale) {
100910
101444
  const host = this.requireHost();
100911
101445
  host.activeSlideIndex.set(index);
100912
101446
  await new Promise((resolve) => {
@@ -100916,7 +101450,7 @@ class ViewerExportService {
100916
101450
  if (!el) {
100917
101451
  return null;
100918
101452
  }
100919
- const canvas = await this.exportSvc.renderElement(el);
101453
+ const canvas = await this.exportSvc.renderElement(el, scale ?? host.imageExportScale?.() ?? 2);
100920
101454
  return canvas.toDataURL('image/png');
100921
101455
  }
100922
101456
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -100926,18 +101460,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
100926
101460
  type: Injectable
100927
101461
  }] });
100928
101462
 
100929
- /** Build the ZIP downloaded by the File tab's Package for Sharing action. */
100930
- async function buildSharingPackage(presentation, presentationFilename) {
100931
- const zip = new JSZip();
100932
- const folder = zip.folder('presentation-package');
100933
- if (!folder) {
100934
- throw new Error('Unable to create presentation package');
100935
- }
100936
- folder.file(presentationFilename, presentation);
100937
- folder.file('README.txt', generatePackageReadme(presentationFilename));
100938
- return zip.generateAsync({ type: 'blob' });
100939
- }
100940
-
100941
101463
  /**
100942
101464
  * viewer-file-io.service.ts: Viewer-scoped state + logic for getting `.pptx`
100943
101465
  * bytes in and out of the viewer: the built-in File ▸ Open override signal (a
@@ -101019,6 +101541,7 @@ class ViewerFileIOService {
101019
101541
  : await this.loader.saveSlides(this.loader.slides(), format, undefined, intent);
101020
101542
  host.emitContentChange(bytes);
101021
101543
  this.exportSvc.savePresentation(bytes, `presentation.${format}`, format);
101544
+ host.afterSuccessfulSave(format);
101022
101545
  }
101023
101546
  async saveAsPptx() {
101024
101547
  await this.saveAs('pptx');
@@ -101054,12 +101577,6 @@ class ViewerFileIOService {
101054
101577
  presentationProperties: this.loader.presentationProperties(),
101055
101578
  }, sourceName);
101056
101579
  }
101057
- /** Bundle the presentation and its usage notes in a shareable ZIP archive. */
101058
- async packageForSharing() {
101059
- const presentationFilename = 'presentation.pptx';
101060
- const blob = await buildSharingPackage(await this.getContent(), presentationFilename);
101061
- downloadBlob(blob, 'presentation-package.zip');
101062
- }
101063
101580
  /**
101064
101581
  * File ▸ Open: host override (`onOpenFile` input) takes precedence; otherwise
101065
101582
  * a built-in native picker loads the chosen presentation in place.
@@ -101616,134 +102133,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
101616
102133
  type: Injectable
101617
102134
  }] });
101618
102135
 
101619
- /**
101620
- * viewer-options.service.ts: signal-based owner of the File > Options store for
101621
- * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
101622
- *
101623
- * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
101624
- * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
101625
- * Angular signal, and bundles the option-to-behavior helpers the rest of the
101626
- * viewer consumes: history depth, autosave cadence, print defaults, screen
101627
- * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
101628
- * protected view, and the Options > Save cache purge.
101629
- *
101630
- * Deliberately constructible with plain `new` (no required injection context)
101631
- * so the colocated unit tests can exercise it without TestBed, matching
101632
- * {@link EditorStateService}'s optional-inject pattern.
101633
- */
101634
- class ViewerOptionsService {
101635
- constructor() {
101636
- /**
101637
- * Optional: `inject()` needs an active injection context, which plain
101638
- * `new ViewerOptionsService()` (used by the colocated unit tests) does not
101639
- * provide. Outside DI the subscription simply lives as long as the instance.
101640
- */
101641
- this.destroyRef = (() => {
101642
- try {
101643
- return inject(DestroyRef);
101644
- }
101645
- catch {
101646
- return null;
101647
- }
101648
- })();
101649
- this.translate = (() => {
101650
- try {
101651
- return inject(TranslateService);
101652
- }
101653
- catch {
101654
- return null;
101655
- }
101656
- })();
101657
- /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
101658
- this.store = createViewerOptionsStore();
101659
- this._options = signal(this.store.getOptions(), /* @ts-ignore */
101660
- ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
101661
- /** Reactive File > Options snapshot; a new object per change. */
101662
- this.options = this._options.asReadonly();
101663
- const unsubscribe = this.store.subscribe((next) => this._options.set(next));
101664
- this.destroyRef?.onDestroy(unsubscribe);
101665
- }
101666
- // ── Store mutations ─────────────────────────────────────────────────────
101667
- setValue(group, key, value) {
101668
- this.store.setValue(group, key, value);
101669
- }
101670
- setRibbonTabHidden(tabId, hidden) {
101671
- this.store.setRibbonTabHidden(tabId, hidden);
101672
- }
101673
- setQuickAccessCommands(commandIds) {
101674
- this.store.setQuickAccessCommands(commandIds);
101675
- }
101676
- reset(group) {
101677
- this.store.reset(group);
101678
- }
101679
- /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
101680
- restore(snapshot) {
101681
- this.store.setOptions(snapshot);
101682
- }
101683
- // ── Behavior resolution helpers ─────────────────────────────────────────
101684
- /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
101685
- historyDepth() {
101686
- return resolveHistoryDepth(this.options());
101687
- }
101688
- /** AutoRecover cadence in seconds for the autosave engine. */
101689
- autosaveIntervalSeconds() {
101690
- return resolveAutosaveIntervalSeconds(this.options());
101691
- }
101692
- /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
101693
- printDefaults() {
101694
- return resolveDefaultPrintSettings(this.options());
101695
- }
101696
- /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
101697
- rootClasses() {
101698
- return resolveOptionRootClasses(this.options(), 'pptx-ng');
101699
- }
101700
- /** Tooltip text under the current ScreenTip style (undefined = suppress). */
101701
- screenTip(label, description, shortcut) {
101702
- return resolveScreenTip(this.options(), label, description, shortcut);
101703
- }
101704
- /** Run the enabled AutoCorrect rules over a committed run of text. */
101705
- autoCorrect(text) {
101706
- return applyAutoCorrect(text, this.options().proofing);
101707
- }
101708
- /** Play the Accessibility "feedback with sound" cue for a completed action. */
101709
- playFeedback() {
101710
- playFeedbackSound(this.options());
101711
- }
101712
- /** Whether Trust Center forces the deck to open read-only. */
101713
- protectedView() {
101714
- return shouldOpenInProtectedView(this.options());
101715
- }
101716
- /**
101717
- * Gate an external hyperlink activation. Returns `true` when navigation may
101718
- * proceed (no confirmation required, or the user confirmed the prompt).
101719
- */
101720
- confirmExternalHyperlink(href) {
101721
- if (!shouldConfirmExternalHyperlink(this.options(), href)) {
101722
- return true;
101723
- }
101724
- if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
101725
- return true;
101726
- }
101727
- const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
101728
- 'Confirm before opening external hyperlinks';
101729
- return window.confirm(`${label}\n\n${href}`);
101730
- }
101731
- /**
101732
- * Options > Save > "Delete cached files": purge every autosave recovery
101733
- * snapshot from the shared IndexedDB store. Resolves with the purge count.
101734
- */
101735
- async clearCache() {
101736
- const snapshots = await listAutosaveSnapshots();
101737
- await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
101738
- return snapshots.length;
101739
- }
101740
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
101741
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService }); }
101742
- }
101743
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, decorators: [{
101744
- type: Injectable
101745
- }], ctorParameters: () => [] });
101746
-
101747
102136
  /**
101748
102137
  * Whether a click/tap/swipe advance must be swallowed instead of moving to the
101749
102138
  * next slide. A click still steps the current slide's remaining animation
@@ -103481,6 +103870,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
103481
103870
  args: [{ selector: 'pptx-presentation-annotation-overlay', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle], template: "@if (isArmed()) {\n\t<div\n\t\tclass=\"pptx-ng-anno-wrapper\"\n\t\t[ngStyle]=\"wrapperStyle()\"\n\t\t(pointerdown)=\"onPointerDown($event)\"\n\t\t(pointermove)=\"onPointerMove($event)\"\n\t\t(pointerup)=\"onPointerUp($event)\"\n\t\t(pointerleave)=\"onPointerLeave($event)\"\n\t>\n\t\t<svg\n\t\t\t#svg\n\t\t\tclass=\"pptx-ng-anno-svg\"\n\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t[attr.viewBox]=\"viewBox()\"\n\t\t\t[ngStyle]=\"svgStyle()\"\n\t\t>\n\t\t\t@for (s of allStrokes(); track s.id) {\n\t\t\t\t<path\n\t\t\t\t\t[attr.d]=\"strokePath(s.points)\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t[attr.stroke]=\"s.color\"\n\t\t\t\t\t[attr.stroke-width]=\"s.width\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t[attr.opacity]=\"s.opacity\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</svg>\n\n\t\t@if (service.tool() === 'laser' && service.laserPosition(); as lp) {\n\t\t\t<div class=\"pptx-ng-laser-dot\" [ngStyle]=\"laserDotStyle(lp.x, lp.y)\"></div>\n\t\t}\n\t</div>\n}\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none}.pptx-ng-anno-wrapper{position:absolute;inset:0}.pptx-ng-anno-svg{position:absolute;top:0;left:0;transform-origin:top left;overflow:visible}.pptx-ng-laser-dot{position:absolute;border-radius:50%;pointer-events:none;background:#ff0000d9;box-shadow:0 0 12px 6px #ff000080,0 0 24px 12px #ff000040;filter:drop-shadow(0 0 8px rgba(255,0,0,.7))}\n"] }]
103482
103871
  }], propDecorators: { canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], svgRef: [{ type: i0.ViewChild, args: ['svg', { isSignal: true }] }] } });
103483
103872
 
103873
+ /**
103874
+ * presentation-context-menu.component.ts: right-click menu shown while
103875
+ * presenting.
103876
+ *
103877
+ * Selector: `pptx-presentation-context-menu`
103878
+ *
103879
+ * Item order/grouping/i18n keys come from the shared
103880
+ * `getPresentationContextMenuSections` (`pptx-viewer-shared`), the same
103881
+ * source React's `PresentationContextMenu` and Vue's `PresentationMode`
103882
+ * render from, so this menu cannot drift from theirs. This component only
103883
+ * describes what capabilities are available (always all of them here: the
103884
+ * overlay already has next/prev, See All Slides, presenter view, pointer
103885
+ * tools, and the black/white blank screen) and routes a chosen action id
103886
+ * back to the overlay via a single output.
103887
+ *
103888
+ * Closes on Escape and on an outside pointerdown, matching
103889
+ * `EditorContextMenuComponent`.
103890
+ */
103891
+ class PresentationContextMenuComponent {
103892
+ constructor() {
103893
+ /** Horizontal viewport coordinate (px) of the top-left corner of the menu. */
103894
+ this.x = input.required(/* @ts-ignore */
103895
+ ...(ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []));
103896
+ /** Vertical viewport coordinate (px) of the top-left corner of the menu. */
103897
+ this.y = input.required(/* @ts-ignore */
103898
+ ...(ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []));
103899
+ /** Emitted when the menu should close (Escape, outside click, or after an action). */
103900
+ this.closed = output();
103901
+ /** The chosen action id; the overlay maps it onto its own navigator/annotations/etc. */
103902
+ this.action = output();
103903
+ this.host = inject(ElementRef);
103904
+ this.sections = computed(() => getPresentationContextMenuSections({
103905
+ seeAllSlides: true,
103906
+ presenterView: true,
103907
+ pointerTools: true,
103908
+ eraseInk: true,
103909
+ blankBlack: true,
103910
+ blankWhite: true,
103911
+ }), /* @ts-ignore */
103912
+ ...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
103913
+ }
103914
+ onEscape() {
103915
+ this.closed.emit();
103916
+ }
103917
+ onDocumentPointerDown(event) {
103918
+ const target = event.target;
103919
+ if (!(target instanceof Node)) {
103920
+ return;
103921
+ }
103922
+ if (!this.host.nativeElement.contains(target)) {
103923
+ this.closed.emit();
103924
+ }
103925
+ }
103926
+ run(id) {
103927
+ this.action.emit(id);
103928
+ this.closed.emit();
103929
+ }
103930
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
103931
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationContextMenuComponent, isStandalone: true, selector: "pptx-presentation-context-menu", inputs: { x: { classPropertyName: "x", publicName: "x", isSignal: true, isRequired: true, transformFunction: null }, y: { classPropertyName: "y", publicName: "y", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed", action: "action" }, host: { listeners: { "document:keydown.escape": "onEscape()", "document:pointerdown": "onDocumentPointerDown($event)" }, properties: { "style.--pptx-ctx-x": "x() + \"px\"", "style.--pptx-ctx-y": "y() + \"px\"" } }, ngImport: i0, template: `
103932
+ <ul
103933
+ class="pptx-ctx__menu"
103934
+ data-pptx-presentation-menu="true"
103935
+ role="menu"
103936
+ (contextmenu)="$event.preventDefault()"
103937
+ >
103938
+ @for (section of sections(); track section.id; let sectionIndex = $index) {
103939
+ @if (sectionIndex > 0) {
103940
+ <li role="separator" class="pptx-ctx__divider"></li>
103941
+ }
103942
+ @for (item of section.items; track item.id) {
103943
+ <li role="none">
103944
+ <button type="button" class="pptx-ctx__item" role="menuitem" (click)="run(item.id)">
103945
+ {{ item.labelKey | translate }}
103946
+ </button>
103947
+ </li>
103948
+ }
103949
+ }
103950
+ </ul>
103951
+ `, isInline: true, styles: [":host{position:fixed;left:var(--pptx-ctx-x, 0px);top:var(--pptx-ctx-y, 0px);z-index:9000;display:block}.pptx-ctx__menu{list-style:none;margin:0;padding:4px 0;min-width:160px;background:var(--pptx-ctx-bg, #252526);color:var(--pptx-ctx-fg, #e0e0e0);border:1px solid var(--pptx-ctx-border, #454545);border-radius:4px;box-shadow:0 4px 12px #0006,0 1px 3px #0000004d;font-size:13px;-webkit-user-select:none;user-select:none}.pptx-ctx__item{display:block;width:100%;padding:5px 14px;background:transparent;border:none;color:inherit;text-align:left;cursor:pointer;font-size:inherit;white-space:nowrap}.pptx-ctx__item:hover:not(:disabled){background:var(--pptx-ctx-hover, #094771);color:var(--pptx-ctx-hover-fg, #ffffff)}.pptx-ctx__item:disabled{opacity:.4;pointer-events:none;cursor:default}.pptx-ctx__item--danger{color:var(--pptx-ctx-danger, #f47c7c)}.pptx-ctx__item--danger:hover:not(:disabled){background:var(--pptx-ctx-danger-hover, #4a1a1a);color:var(--pptx-ctx-danger-fg, #ffaaaa)}.pptx-ctx__divider{height:1px;background:var(--pptx-ctx-divider, #454545);margin:3px 0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
103952
+ }
103953
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationContextMenuComponent, decorators: [{
103954
+ type: Component,
103955
+ args: [{ selector: 'pptx-presentation-context-menu', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
103956
+ <ul
103957
+ class="pptx-ctx__menu"
103958
+ data-pptx-presentation-menu="true"
103959
+ role="menu"
103960
+ (contextmenu)="$event.preventDefault()"
103961
+ >
103962
+ @for (section of sections(); track section.id; let sectionIndex = $index) {
103963
+ @if (sectionIndex > 0) {
103964
+ <li role="separator" class="pptx-ctx__divider"></li>
103965
+ }
103966
+ @for (item of section.items; track item.id) {
103967
+ <li role="none">
103968
+ <button type="button" class="pptx-ctx__item" role="menuitem" (click)="run(item.id)">
103969
+ {{ item.labelKey | translate }}
103970
+ </button>
103971
+ </li>
103972
+ }
103973
+ }
103974
+ </ul>
103975
+ `, host: {
103976
+ '[style.--pptx-ctx-x]': 'x() + "px"',
103977
+ '[style.--pptx-ctx-y]': 'y() + "px"',
103978
+ }, styles: [":host{position:fixed;left:var(--pptx-ctx-x, 0px);top:var(--pptx-ctx-y, 0px);z-index:9000;display:block}.pptx-ctx__menu{list-style:none;margin:0;padding:4px 0;min-width:160px;background:var(--pptx-ctx-bg, #252526);color:var(--pptx-ctx-fg, #e0e0e0);border:1px solid var(--pptx-ctx-border, #454545);border-radius:4px;box-shadow:0 4px 12px #0006,0 1px 3px #0000004d;font-size:13px;-webkit-user-select:none;user-select:none}.pptx-ctx__item{display:block;width:100%;padding:5px 14px;background:transparent;border:none;color:inherit;text-align:left;cursor:pointer;font-size:inherit;white-space:nowrap}.pptx-ctx__item:hover:not(:disabled){background:var(--pptx-ctx-hover, #094771);color:var(--pptx-ctx-hover-fg, #ffffff)}.pptx-ctx__item:disabled{opacity:.4;pointer-events:none;cursor:default}.pptx-ctx__item--danger{color:var(--pptx-ctx-danger, #f47c7c)}.pptx-ctx__item--danger:hover:not(:disabled){background:var(--pptx-ctx-danger-hover, #4a1a1a);color:var(--pptx-ctx-danger-fg, #ffaaaa)}.pptx-ctx__divider{height:1px;background:var(--pptx-ctx-divider, #454545);margin:3px 0}\n"] }]
103979
+ }], propDecorators: { x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: true }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: true }] }], closed: [{ type: i0.Output, args: ["closed"] }], action: [{ type: i0.Output, args: ["action"] }], onEscape: [{
103980
+ type: HostListener,
103981
+ args: ['document:keydown.escape']
103982
+ }], onDocumentPointerDown: [{
103983
+ type: HostListener,
103984
+ args: ['document:pointerdown', ['$event']]
103985
+ }] } });
103986
+
103484
103987
  /**
103485
103988
  * presentation-fullscreen.ts
103486
103989
  *
@@ -103778,13 +104281,31 @@ class PresentationInputController {
103778
104281
  /**
103779
104282
  * Run any on-slide action under the pointer, and report what the click left
103780
104283
  * for the show: only `'advance'` reaches {@link advanceFromClick}.
104284
+ *
104285
+ * Reimplements `handlePresentationStageClick`'s classify-then-run in two
104286
+ * steps (rather than calling it directly) so an `openUrl` intent can be
104287
+ * gated by Trust Center > "Confirm before opening external hyperlinks"
104288
+ * before the navigation actually runs. A declined confirmation still
104289
+ * consumes the click (PowerPoint does not also advance the slide).
103781
104290
  */
103782
104291
  handleActionClick(target) {
103783
- return handlePresentationStageClick(target, this.deps.currentSlide(), { slideCount: this.deps.slides().length }, {
104292
+ const outcome = resolvePresentationClick(target, this.deps.currentSlide());
104293
+ if (outcome.kind !== 'action') {
104294
+ return outcome.kind;
104295
+ }
104296
+ const options = { slideCount: this.deps.slides().length };
104297
+ const { intent } = resolvePresentationAction(outcome.action, options);
104298
+ if (intent.kind === 'openUrl' &&
104299
+ this.deps.confirmExternalHyperlink &&
104300
+ !this.deps.confirmExternalHyperlink(intent.url)) {
104301
+ return 'action';
104302
+ }
104303
+ runPresentationAction(outcome.action, options, {
103784
104304
  goToSlide: (index) => this.deps.navigator.goToSlide(index),
103785
104305
  move: (direction) => this.deps.navigator.navigate(direction > 0 ? 'next' : 'prev'),
103786
104306
  endShow: () => this.deps.requestClose(),
103787
104307
  });
104308
+ return 'action';
103788
104309
  }
103789
104310
  /**
103790
104311
  * Click/tap/swipe advance. Like every forward step it first reveals the
@@ -104582,6 +105103,13 @@ class PresentationToolbarComponent {
104582
105103
  /** Whether presenter view is currently up (tints the toggle). */
104583
105104
  this.presenterMode = input(false, /* @ts-ignore */
104584
105105
  ...(ngDevMode ? [{ debugName: "presenterMode" }] : /* istanbul ignore next */ []));
105106
+ /**
105107
+ * File > Options > Advanced > "Show popup toolbar" (default true). When
105108
+ * `false`, `mousemove` never auto-reveals the bar; `toggleVisible`
105109
+ * (PowerPoint's Ctrl+H) still works.
105110
+ */
105111
+ this.popupToolbarEnabled = input(true, /* @ts-ignore */
105112
+ ...(ngDevMode ? [{ debugName: "popupToolbarEnabled" }] : /* istanbul ignore next */ []));
104585
105113
  /** Step the show by one slide (`-1` back, `1` forward). */
104586
105114
  this.move = output();
104587
105115
  /** Leave the show. */
@@ -104652,6 +105180,9 @@ class PresentationToolbarComponent {
104652
105180
  * back on the next twitch.
104653
105181
  */
104654
105182
  onDocumentMouseMove(event) {
105183
+ if (!this.popupToolbarEnabled()) {
105184
+ return;
105185
+ }
104655
105186
  const surface = this.host.nativeElement.parentElement;
104656
105187
  if (surface) {
104657
105188
  const rect = surface.getBoundingClientRect();
@@ -104753,7 +105284,7 @@ class PresentationToolbarComponent {
104753
105284
  this.openPalette.update((open) => (open === kind ? 'none' : kind));
104754
105285
  }
104755
105286
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
104756
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationToolbarComponent, isStandalone: true, selector: "pptx-presentation-toolbar", inputs: { currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, totalSlides: { classPropertyName: "totalSlides", publicName: "totalSlides", isSignal: true, isRequired: true, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { move: "move", endPresentation: "endPresentation", presenterViewToggle: "presenterViewToggle" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "document:mousemove": "onDocumentMouseMove($event)", "document:mousedown": "onDocumentMouseDown($event)" }, properties: { "class": "ui.wrapper", "style.opacity": "visible() ? 1 : 0", "style.pointer-events": "visible() ? \"auto\" : \"none\"" } }, ngImport: i0, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucidePanelRight, selector: "svg[lucidePanelRight]" }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucidePresentation, selector: "svg[lucidePresentation]" }, { kind: "component", type: LucideTimer, selector: "svg[lucideTimer]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
105287
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationToolbarComponent, isStandalone: true, selector: "pptx-presentation-toolbar", inputs: { currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, totalSlides: { classPropertyName: "totalSlides", publicName: "totalSlides", isSignal: true, isRequired: true, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, popupToolbarEnabled: { classPropertyName: "popupToolbarEnabled", publicName: "popupToolbarEnabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { move: "move", endPresentation: "endPresentation", presenterViewToggle: "presenterViewToggle" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "document:mousemove": "onDocumentMouseMove($event)", "document:mousedown": "onDocumentMouseDown($event)" }, properties: { "class": "ui.wrapper", "style.opacity": "visible() ? 1 : 0", "style.pointer-events": "visible() ? \"auto\" : \"none\"" } }, ngImport: i0, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucidePanelRight, selector: "svg[lucidePanelRight]" }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucidePresentation, selector: "svg[lucidePresentation]" }, { kind: "component", type: LucideTimer, selector: "svg[lucideTimer]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
104757
105288
  }
104758
105289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationToolbarComponent, decorators: [{
104759
105290
  type: Component,
@@ -104778,7 +105309,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
104778
105309
  '(mouseenter)': 'onMouseEnter()',
104779
105310
  '(mouseleave)': 'onMouseLeave()',
104780
105311
  }, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"] }]
104781
- }], ctorParameters: () => [], propDecorators: { currentSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSlideIndex", required: true }] }], totalSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalSlides", required: true }] }], presentationStartTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStartTime", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], move: [{ type: i0.Output, args: ["move"] }], endPresentation: [{ type: i0.Output, args: ["endPresentation"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], onDocumentMouseMove: [{
105312
+ }], ctorParameters: () => [], propDecorators: { currentSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSlideIndex", required: true }] }], totalSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalSlides", required: true }] }], presentationStartTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStartTime", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], popupToolbarEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupToolbarEnabled", required: false }] }], move: [{ type: i0.Output, args: ["move"] }], endPresentation: [{ type: i0.Output, args: ["endPresentation"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], onDocumentMouseMove: [{
104782
105313
  type: HostListener,
104783
105314
  args: ['document:mousemove', ['$event']]
104784
105315
  }], onDocumentMouseDown: [{
@@ -105561,6 +106092,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
105561
106092
  class PresentationOverlayComponent {
105562
106093
  constructor() {
105563
106094
  this.presenterWindow = inject(PresenterWindowService);
106095
+ /**
106096
+ * Optional so this overlay still renders in isolation (Storybook-style
106097
+ * usage, tests): outside a `PowerPointViewerComponent` host that provides
106098
+ * it, external-hyperlink clicks are simply never confirmed.
106099
+ */
106100
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
105564
106101
  // ------------------------------------------------------------------
105565
106102
  // Inputs
105566
106103
  // ------------------------------------------------------------------
@@ -105610,6 +106147,15 @@ class PresentationOverlayComponent {
105610
106147
  /** Whether presenter view is up (tints the toolbar's presenter-view toggle). */
105611
106148
  this.presenterMode = input(false, /* @ts-ignore */
105612
106149
  ...(ngDevMode ? [{ debugName: "presenterMode" }] : /* istanbul ignore next */ []));
106150
+ /**
106151
+ * File > Options > Advanced > "Show menu on right mouse click". Off swallows
106152
+ * right-click entirely (no browser menu either), matching React/Vue.
106153
+ */
106154
+ this.showMenuOnRightClick = input(true, /* @ts-ignore */
106155
+ ...(ngDevMode ? [{ debugName: "showMenuOnRightClick" }] : /* istanbul ignore next */ []));
106156
+ /** File > Options > Advanced > "Show popup toolbar" while presenting. */
106157
+ this.showPopupToolbar = input(true, /* @ts-ignore */
106158
+ ...(ngDevMode ? [{ debugName: "showPopupToolbar" }] : /* istanbul ignore next */ []));
105613
106159
  // ------------------------------------------------------------------
105614
106160
  // Outputs
105615
106161
  // ------------------------------------------------------------------
@@ -105679,10 +106225,17 @@ class PresentationOverlayComponent {
105679
106225
  // the shortcut mean something else.
105680
106226
  showAllSlides: () => this.allSlidesOpen.set(true),
105681
106227
  requestClose: () => this.emitClosed(),
106228
+ // Trust Center > "Confirm before opening external hyperlinks" (File >
106229
+ // Options), gating a slide's on-click `a:hlinkClick` action the same way
106230
+ // it gates a text-run hyperlink.
106231
+ confirmExternalHyperlink: (href) => this.viewerOpts?.confirmExternalHyperlink(href) ?? true,
105682
106232
  });
105683
106233
  /** Whether PowerPoint's "See All Slides" navigator is up (Ctrl+S). */
105684
106234
  this.allSlidesOpen = signal(false, /* @ts-ignore */
105685
106235
  ...(ngDevMode ? [{ debugName: "allSlidesOpen" }] : /* istanbul ignore next */ []));
106236
+ /** Slide-show right-click menu position, or null when closed. */
106237
+ this.contextMenuState = signal(null, /* @ts-ignore */
106238
+ ...(ngDevMode ? [{ debugName: "contextMenuState" }] : /* istanbul ignore next */ []));
105686
106239
  /** Template aliases for the navigator's state. */
105687
106240
  this.currentIndex = this.navigator.currentIndex;
105688
106241
  this.endOfShow = this.navigator.endOfShow;
@@ -105963,6 +106516,65 @@ class PresentationOverlayComponent {
105963
106516
  onBodyClick(event) {
105964
106517
  this.input.handleBodyClick(event);
105965
106518
  }
106519
+ /**
106520
+ * Options > Advanced > "Show menu on right mouse click": right-click opens
106521
+ * a minimal Next/Previous/End Show menu (plus pointer tools, See All
106522
+ * Slides, presenter view and the black/white blank screen); off swallows
106523
+ * the click entirely, matching React/Vue.
106524
+ */
106525
+ onStageContextMenu(event) {
106526
+ event.preventDefault();
106527
+ if (!this.showMenuOnRightClick()) {
106528
+ return;
106529
+ }
106530
+ this.contextMenuState.set({ x: event.clientX, y: event.clientY });
106531
+ }
106532
+ /** Route a chosen context-menu action onto this overlay's own handlers. */
106533
+ onContextMenuAction(id) {
106534
+ switch (id) {
106535
+ case 'next':
106536
+ this.navigator.navigate('next');
106537
+ break;
106538
+ case 'previous':
106539
+ this.navigator.navigate('prev');
106540
+ break;
106541
+ case 'seeAllSlides':
106542
+ this.allSlidesOpen.set(true);
106543
+ break;
106544
+ case 'presenterView':
106545
+ this.presenterViewToggle.emit();
106546
+ break;
106547
+ case 'pointerArrow':
106548
+ this.annotations.setTool('none');
106549
+ break;
106550
+ case 'pointerPen':
106551
+ this.annotations.setTool('pen');
106552
+ break;
106553
+ case 'pointerHighlighter':
106554
+ this.annotations.setTool('highlighter');
106555
+ break;
106556
+ case 'pointerLaser':
106557
+ this.annotations.setTool('laser');
106558
+ break;
106559
+ case 'eraseInk':
106560
+ this.annotations.clearAnnotations();
106561
+ break;
106562
+ case 'blankBlack':
106563
+ this.setBlankScreen('black');
106564
+ break;
106565
+ case 'blankWhite':
106566
+ this.setBlankScreen('white');
106567
+ break;
106568
+ case 'endShow':
106569
+ this.emitClosed();
106570
+ break;
106571
+ }
106572
+ }
106573
+ /** Set (or clear) the whole-screen blank, mirroring the keyboard B/W shortcuts. */
106574
+ setBlankScreen(value) {
106575
+ const current = this.presenterWindow.snapshot().blackout;
106576
+ this.presenterWindow.updateSnapshot({ blackout: current === value ? 'none' : value });
106577
+ }
105966
106578
  /** Click on the end screen: exit the show, like PowerPoint's "click to exit". */
105967
106579
  onEndScreenClick(event) {
105968
106580
  event.stopPropagation();
@@ -106019,7 +106631,7 @@ class PresentationOverlayComponent {
106019
106631
  this.closed.emit();
106020
106632
  }
106021
106633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
106022
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"$event.preventDefault()\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
106634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, showMenuOnRightClick: { classPropertyName: "showMenuOnRightClick", publicName: "showMenuOnRightClick", isSignal: true, isRequired: false, transformFunction: null }, showPopupToolbar: { classPropertyName: "showPopupToolbar", publicName: "showPopupToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode", "popupToolbarEnabled"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresentationContextMenuComponent, selector: "pptx-presentation-context-menu", inputs: ["x", "y"], outputs: ["closed", "action"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
106023
106635
  }
106024
106636
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
106025
106637
  type: Component,
@@ -106030,13 +106642,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
106030
106642
  PresentationAnnotationOverlayComponent,
106031
106643
  PresentationSubtitleBarComponent,
106032
106644
  PresentationToolbarComponent,
106645
+ PresentationContextMenuComponent,
106033
106646
  PresenterSlideNavigatorComponent,
106034
106647
  TranslatePipe,
106035
106648
  LucideX,
106036
106649
  LucideChevronLeft,
106037
106650
  LucideChevronRight,
106038
- ], providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"$event.preventDefault()\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
106039
- }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], activeCustomShow: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCustomShow", required: false }] }], showWithAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWithAnimation", required: false }] }], useTimings: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTimings", required: false }] }], subtitlesVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitlesVisible", required: false }] }], sessionEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionEnded", required: false }] }], endWithBlackSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWithBlackSlide", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], subtitlesChange: [{ type: i0.Output, args: ["subtitlesChange"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], annotationsExit: [{ type: i0.Output, args: ["annotationsExit"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], rootRef: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], toolbarRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => PresentationToolbarComponent), { isSignal: true }] }], onWheel: [{
106651
+ ], providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
106652
+ }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], activeCustomShow: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCustomShow", required: false }] }], showWithAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWithAnimation", required: false }] }], useTimings: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTimings", required: false }] }], subtitlesVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitlesVisible", required: false }] }], sessionEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionEnded", required: false }] }], endWithBlackSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWithBlackSlide", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], showMenuOnRightClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMenuOnRightClick", required: false }] }], showPopupToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPopupToolbar", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], subtitlesChange: [{ type: i0.Output, args: ["subtitlesChange"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], annotationsExit: [{ type: i0.Output, args: ["annotationsExit"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], rootRef: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], toolbarRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => PresentationToolbarComponent), { isSignal: true }] }], onWheel: [{
106040
106653
  type: HostListener,
106041
106654
  args: ['document:wheel', ['$event']]
106042
106655
  }], onFullscreenChange: [{
@@ -107144,6 +107757,13 @@ class PrintDialogComponent {
107144
107757
  /** Default frame-slides from presentation properties. */
107145
107758
  this.defaultFrameSlides = input(undefined, /* @ts-ignore */
107146
107759
  ...(ngDevMode ? [{ debugName: "defaultFrameSlides" }] : /* istanbul ignore next */ []));
107760
+ /**
107761
+ * File > Options > Advanced > Print seed (`ViewerOptionsService.printDefaults`).
107762
+ * `undefined` (Options > "Use the most recently used print settings") leaves
107763
+ * `printWhat`/`colorMode`/`frameSlides` at their hardcoded defaults below.
107764
+ */
107765
+ this.defaultSettings = input(undefined, /* @ts-ignore */
107766
+ ...(ngDevMode ? [{ debugName: "defaultSettings" }] : /* istanbul ignore next */ []));
107147
107767
  /** Emits the resolved, validated settings when the user clicks Print. */
107148
107768
  this.print = output();
107149
107769
  /** Emits when the dialog is dismissed (Cancel / Escape / backdrop). */
@@ -107186,10 +107806,14 @@ class PrintDialogComponent {
107186
107806
  }
107187
107807
  this._seeded = true;
107188
107808
  const total = this.slides().length;
107809
+ const optionDefaults = this.defaultSettings();
107189
107810
  this.settings.set({
107190
107811
  ...DEFAULT_PRINT_SETTINGS,
107812
+ printWhat: optionDefaults?.printWhat ?? DEFAULT_PRINT_SETTINGS.printWhat,
107813
+ colorMode: optionDefaults?.colorMode ?? DEFAULT_PRINT_SETTINGS.colorMode,
107191
107814
  slidesPerPage: normalizeSlidesPerPage(this.defaultSlidesPerPage()),
107192
- frameSlides: this.defaultFrameSlides() ?? false,
107815
+ frameSlides: optionDefaults?.frameSlides ?? this.defaultFrameSlides() ?? false,
107816
+ scaleToFit: optionDefaults?.scaleToFit ?? DEFAULT_PRINT_SETTINGS.scaleToFit,
107193
107817
  customRangeFrom: 1,
107194
107818
  customRangeTo: Math.max(1, total),
107195
107819
  });
@@ -107222,7 +107846,7 @@ class PrintDialogComponent {
107222
107846
  }
107223
107847
  }
107224
107848
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
107225
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: PrintDialogComponent, isStandalone: true, selector: "pptx-print-dialog", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, defaultSlidesPerPage: { classPropertyName: "defaultSlidesPerPage", publicName: "defaultSlidesPerPage", isSignal: true, isRequired: false, transformFunction: null }, defaultFrameSlides: { classPropertyName: "defaultFrameSlides", publicName: "defaultFrameSlides", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { print: "print", cancel: "cancel" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, providers: [IsMobileService], ngImport: i0, template: `
107849
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: PrintDialogComponent, isStandalone: true, selector: "pptx-print-dialog", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, defaultSlidesPerPage: { classPropertyName: "defaultSlidesPerPage", publicName: "defaultSlidesPerPage", isSignal: true, isRequired: false, transformFunction: null }, defaultFrameSlides: { classPropertyName: "defaultFrameSlides", publicName: "defaultFrameSlides", isSignal: true, isRequired: false, transformFunction: null }, defaultSettings: { classPropertyName: "defaultSettings", publicName: "defaultSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { print: "print", cancel: "cancel" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, providers: [IsMobileService], ngImport: i0, template: `
107226
107850
  <div
107227
107851
  class="pptx-ng-print-dialog__backdrop"
107228
107852
  [class.is-mobile]="mobile.isMobile()"
@@ -107337,7 +107961,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
107337
107961
  </div>
107338
107962
  </div>
107339
107963
  `, styles: [".pptx-ng-print-dialog__backdrop{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;justify-content:center;background:#0009;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-print-dialog{display:flex;flex-direction:column;width:780px;max-width:calc(100vw - 2rem);max-height:90vh;border:1px solid rgba(255,255,255,.12);border-radius:.75rem;background:#1e1e1e;color:#e5e5e5;box-shadow:0 20px 60px #0009}.pptx-ng-print-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1)}.pptx-ng-print-dialog__title{margin:0;font-size:.875rem;font-weight:600;color:#fff}.pptx-ng-print-dialog__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;border:0;border-radius:.25rem;background:transparent;color:#fff9;font-size:.75rem;cursor:pointer;transition:background .12s,color .12s}.pptx-ng-print-dialog__icon-btn:hover{background:#ffffff1a;color:#fff}.pptx-ng-print-dialog__body{flex:1;overflow-y:auto;padding:1rem 1.25rem}.pptx-ng-print-dialog__footer{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1.25rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-print-dialog__estimate{font-size:.75rem;color:#ffffff80}.pptx-ng-print-dialog__actions{display:flex;gap:.5rem}.pptx-ng-print-dialog__btn{padding:.5rem 1rem;border:1px solid rgba(255,255,255,.15);border-radius:.5rem;background:#ffffff0a;color:#ffffffb3;font-size:.8125rem;cursor:pointer;transition:background .12s,color .12s,border-color .12s}.pptx-ng-print-dialog__btn:hover{background:#ffffff1a;color:#fff}.pptx-ng-print-dialog__btn--primary{border-color:#3b82f6;background:#3b82f6;color:#fff}.pptx-ng-print-dialog__btn--primary:hover{background:#2f6fd6}.pptx-ng-print-dialog__backdrop.is-mobile{align-items:flex-end}.pptx-ng-print-dialog.is-mobile{width:100%;max-width:none;max-height:88dvh;border-left:none;border-right:none;border-bottom:none;border-top-left-radius:1rem;border-top-right-radius:1rem;border-bottom-left-radius:0;border-bottom-right-radius:0;padding-bottom:max(env(safe-area-inset-bottom),0px)}@media(max-width:767px),(pointer:coarse){.pptx-ng-print-dialog__backdrop{align-items:flex-end}.pptx-ng-print-dialog{width:100%;max-width:none;max-height:88dvh;border-left:none;border-right:none;border-bottom:none;border-top-left-radius:1rem;border-top-right-radius:1rem;border-bottom-left-radius:0;border-bottom-right-radius:0;padding-bottom:max(env(safe-area-inset-bottom),0px)}}\n"] }]
107340
- }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: true }] }], defaultSlidesPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSlidesPerPage", required: false }] }], defaultFrameSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFrameSlides", required: false }] }], print: [{ type: i0.Output, args: ["print"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], onKeydown: [{
107964
+ }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: true }] }], defaultSlidesPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSlidesPerPage", required: false }] }], defaultFrameSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFrameSlides", required: false }] }], defaultSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSettings", required: false }] }], print: [{ type: i0.Output, args: ["print"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], onKeydown: [{
107341
107965
  type: HostListener,
107342
107966
  args: ['document:keydown', ['$event']]
107343
107967
  }] } });
@@ -107643,6 +108267,176 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
107643
108267
  `, styles: [".pptx-ng-props-form{display:flex;flex-direction:column;gap:.75rem}.pptx-ng-props-field{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-props-label{font-size:.75rem;font-weight:500;color:var(--pptx-foreground, #e5e5e5)}.pptx-ng-props-input{width:100%;padding:.375rem .75rem;border-radius:.375rem;border:1px solid var(--pptx-border, #2a2a2a);background:var(--pptx-background, #111);color:var(--pptx-foreground, #e5e5e5);font-size:.8125rem}.pptx-ng-props-input:focus{outline:none;border-color:var(--pptx-primary, #6366f1);box-shadow:0 0 0 1px var(--pptx-primary, #6366f1)}.pptx-ng-props-meta{display:flex;flex-direction:column;gap:.375rem;padding-top:.5rem;border-top:1px solid var(--pptx-border, #2a2a2a)}.pptx-ng-props-meta-row{display:flex;justify-content:space-between;font-size:.75rem}.pptx-ng-props-meta-label{color:var(--pptx-muted-foreground, #9a9a9a)}.pptx-ng-props-meta-value{color:var(--pptx-foreground, #e5e5e5)}.pptx-ng-props-btn{padding:.375rem .75rem;border:none;border-radius:.375rem;background:var(--pptx-muted, #2a2a2a);color:var(--pptx-foreground, #e5e5e5);font-size:.75rem;cursor:pointer}.pptx-ng-props-btn-primary{background:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #fff)}\n"] }]
107644
108268
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: true }] }], save: [{ type: i0.Output, args: ["save"] }], close: [{ type: i0.Output, args: ["close"] }] } });
107645
108269
 
108270
+ /**
108271
+ * quick-access-strip.component.ts: the Quick Access Toolbar strip driven by
108272
+ * File > Options > Quick Access Toolbar.
108273
+ *
108274
+ * Renders the ordered {@link QUICK_ACCESS_COMMAND_CATALOG} commands from
108275
+ * `options.quickAccess.commandIds` as icon buttons (optionally with labels),
108276
+ * emitting the pressed command id; the host maps ids onto its existing
108277
+ * handlers. Replaces the title bar's previously hardcoded Save/Undo/Redo
108278
+ * trio, and is also rendered below the ribbon when the position option is
108279
+ * `below`. Tooltips honour the ScreenTip style via {@link ViewerOptionsService}.
108280
+ */
108281
+ /** Resolve the configured command ids to renderable strip entries. */
108282
+ function resolveQuickAccessItems(commandIds) {
108283
+ const items = [];
108284
+ for (const id of commandIds) {
108285
+ const command = getQuickAccessCommand(id);
108286
+ if (command) {
108287
+ items.push({ id, icon: command.icon, labelKey: command.labelKey });
108288
+ }
108289
+ }
108290
+ return items;
108291
+ }
108292
+ class QuickAccessStripComponent {
108293
+ constructor() {
108294
+ /** The live Quick Access options group (visibility is gated by the host). */
108295
+ this.quickAccess = input.required(/* @ts-ignore */
108296
+ ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
108297
+ this.canUndo = input(false, /* @ts-ignore */
108298
+ ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
108299
+ this.canRedo = input(false, /* @ts-ignore */
108300
+ ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
108301
+ /** A configured command id was pressed. */
108302
+ this.command = output();
108303
+ this.translate = inject(TranslateService);
108304
+ /** Optional so the strip renders outside a full viewer host too. */
108305
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
108306
+ this.tb = TITLE_BAR_CLASSES;
108307
+ this.items = computed(() => resolveQuickAccessItems(this.quickAccess().commandIds), /* @ts-ignore */
108308
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
108309
+ }
108310
+ label(item) {
108311
+ return this.translate.instant(item.labelKey);
108312
+ }
108313
+ /** ScreenTip-styled tooltip (null suppresses the title attribute). */
108314
+ tip(item) {
108315
+ const label = this.label(item);
108316
+ return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
108317
+ }
108318
+ isDisabled(id) {
108319
+ if (id === 'undo') {
108320
+ return !this.canUndo();
108321
+ }
108322
+ if (id === 'redo') {
108323
+ return !this.canRedo();
108324
+ }
108325
+ return false;
108326
+ }
108327
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
108328
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: QuickAccessStripComponent, isStandalone: true, selector: "pptx-quick-access-strip", inputs: { quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: true, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { command: "command" }, ngImport: i0, template: `
108329
+ @for (item of items(); track item.id) {
108330
+ <button
108331
+ type="button"
108332
+ [class]="tb.quickButton"
108333
+ [disabled]="isDisabled(item.id)"
108334
+ [attr.title]="tip(item)"
108335
+ [attr.aria-label]="label(item)"
108336
+ (click)="command.emit(item.id)"
108337
+ >
108338
+ @switch (item.icon) {
108339
+ @case ('save') {
108340
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
108341
+ }
108342
+ @case ('undo') {
108343
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
108344
+ }
108345
+ @case ('redo') {
108346
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
108347
+ }
108348
+ @case ('play') {
108349
+ <svg lucidePlay class="h-3.5 w-3.5"></svg>
108350
+ }
108351
+ @case ('printer') {
108352
+ <svg lucidePrinter class="h-3.5 w-3.5"></svg>
108353
+ }
108354
+ @case ('fileDown') {
108355
+ <svg lucideFileDown class="h-3.5 w-3.5"></svg>
108356
+ }
108357
+ @case ('plus') {
108358
+ <svg lucidePlus class="h-3.5 w-3.5"></svg>
108359
+ }
108360
+ @case ('spellCheck') {
108361
+ <svg lucideSearch class="h-3.5 w-3.5"></svg>
108362
+ }
108363
+ @case ('zoomIn') {
108364
+ <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
108365
+ }
108366
+ @default {
108367
+ <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
108368
+ }
108369
+ }
108370
+ @if (quickAccess().showCommandLabels) {
108371
+ <span class="pptx-ng-qat-label">{{ label(item) }}</span>
108372
+ }
108373
+ </button>
108374
+ }
108375
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucidePlay, selector: "svg[lucidePlay]" }, { kind: "component", type: LucidePrinter, selector: "svg[lucidePrinter]" }, { kind: "component", type: LucideFileDown, selector: "svg[lucideFileDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "component", type: LucideZoomIn, selector: "svg[lucideZoomIn]" }, { kind: "component", type: LucideZoomOut, selector: "svg[lucideZoomOut]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
108376
+ }
108377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, decorators: [{
108378
+ type: Component,
108379
+ args: [{ selector: 'pptx-quick-access-strip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
108380
+ LucideSave,
108381
+ LucideUndo,
108382
+ LucideRedo,
108383
+ LucidePlay,
108384
+ LucidePrinter,
108385
+ LucideFileDown,
108386
+ LucidePlus,
108387
+ LucideSearch,
108388
+ LucideZoomIn,
108389
+ LucideZoomOut,
108390
+ ], template: `
108391
+ @for (item of items(); track item.id) {
108392
+ <button
108393
+ type="button"
108394
+ [class]="tb.quickButton"
108395
+ [disabled]="isDisabled(item.id)"
108396
+ [attr.title]="tip(item)"
108397
+ [attr.aria-label]="label(item)"
108398
+ (click)="command.emit(item.id)"
108399
+ >
108400
+ @switch (item.icon) {
108401
+ @case ('save') {
108402
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
108403
+ }
108404
+ @case ('undo') {
108405
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
108406
+ }
108407
+ @case ('redo') {
108408
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
108409
+ }
108410
+ @case ('play') {
108411
+ <svg lucidePlay class="h-3.5 w-3.5"></svg>
108412
+ }
108413
+ @case ('printer') {
108414
+ <svg lucidePrinter class="h-3.5 w-3.5"></svg>
108415
+ }
108416
+ @case ('fileDown') {
108417
+ <svg lucideFileDown class="h-3.5 w-3.5"></svg>
108418
+ }
108419
+ @case ('plus') {
108420
+ <svg lucidePlus class="h-3.5 w-3.5"></svg>
108421
+ }
108422
+ @case ('spellCheck') {
108423
+ <svg lucideSearch class="h-3.5 w-3.5"></svg>
108424
+ }
108425
+ @case ('zoomIn') {
108426
+ <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
108427
+ }
108428
+ @default {
108429
+ <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
108430
+ }
108431
+ }
108432
+ @if (quickAccess().showCommandLabels) {
108433
+ <span class="pptx-ng-qat-label">{{ label(item) }}</span>
108434
+ }
108435
+ </button>
108436
+ }
108437
+ `, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"] }]
108438
+ }], propDecorators: { quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: true }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], command: [{ type: i0.Output, args: ["command"] }] } });
108439
+
107646
108440
  /**
107647
108441
  * reading-view-overlay.styles.ts: CSS for PowerPoint's Reading View.
107648
108442
  *
@@ -108909,9 +109703,30 @@ class RibbonAnimationsSectionComponent {
108909
109703
  own 420px. Uncapped, five 150px family columns claim ~800px of a
108910
109704
  single-row ribbon and squeeze the Advanced Animation pills beside them
108911
109705
  until their labels overlap.
109706
+
109707
+ shrink-0, not shrink: this section used to opt INTO shrinking
109708
+ (shrink = flex-shrink: 1) with no min-width, and overflow-hidden
109709
+ removes the browser's automatic min-content-size floor a flex item
109710
+ would otherwise get. With the ribbon row tight on space (which is the
109711
+ normal case once Advanced Animation and Timing claim their own
109712
+ content-sized width), ALL of the row's required shrinkage landed on
109713
+ this one section, collapsing it to ~50px wide, i.e. hard-clipping four
109714
+ of the five families (Arcs/Turns/Shapes/Loops), reachable by neither
109715
+ scroll nor sight. pptx-ribbon-animations-section renders with
109716
+ display: contents (see its host below), so the ribbon row's own
109717
+ shrink-0-on-every-child safety net (ribbon.component.ts) never reaches
109718
+ this section either: that rule is a real CSS child combinator, so it
109719
+ lands on the custom element itself, not on the elements its
109720
+ display: contents template promotes up into the row's flex layout.
109721
+ Every element promoted that way needs its own shrink-0, the same fix
109722
+ already applied to the View tab's Eyedropper control (see the
109723
+ shrink-0-on-every-child comment in pptx-angular-viewer.css). shrink-0
109724
+ keeps this section at its own content width (capped at max-w-420px)
109725
+ and lets the row's own horizontal scroll handle any total overflow,
109726
+ same as every other group.
108912
109727
  -->
108913
109728
  <section
108914
- class="relative flex max-w-[420px] shrink items-start gap-1 overflow-hidden pb-3"
109729
+ class="relative flex max-w-[420px] shrink-0 items-start gap-1 overflow-hidden pb-3"
108915
109730
  [attr.aria-label]="'pptx.animation.motionPath' | translate"
108916
109731
  >
108917
109732
  <pptx-ribbon-motion-path-gallery
@@ -109066,9 +109881,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
109066
109881
  own 420px. Uncapped, five 150px family columns claim ~800px of a
109067
109882
  single-row ribbon and squeeze the Advanced Animation pills beside them
109068
109883
  until their labels overlap.
109884
+
109885
+ shrink-0, not shrink: this section used to opt INTO shrinking
109886
+ (shrink = flex-shrink: 1) with no min-width, and overflow-hidden
109887
+ removes the browser's automatic min-content-size floor a flex item
109888
+ would otherwise get. With the ribbon row tight on space (which is the
109889
+ normal case once Advanced Animation and Timing claim their own
109890
+ content-sized width), ALL of the row's required shrinkage landed on
109891
+ this one section, collapsing it to ~50px wide, i.e. hard-clipping four
109892
+ of the five families (Arcs/Turns/Shapes/Loops), reachable by neither
109893
+ scroll nor sight. pptx-ribbon-animations-section renders with
109894
+ display: contents (see its host below), so the ribbon row's own
109895
+ shrink-0-on-every-child safety net (ribbon.component.ts) never reaches
109896
+ this section either: that rule is a real CSS child combinator, so it
109897
+ lands on the custom element itself, not on the elements its
109898
+ display: contents template promotes up into the row's flex layout.
109899
+ Every element promoted that way needs its own shrink-0, the same fix
109900
+ already applied to the View tab's Eyedropper control (see the
109901
+ shrink-0-on-every-child comment in pptx-angular-viewer.css). shrink-0
109902
+ keeps this section at its own content width (capped at max-w-420px)
109903
+ and lets the row's own horizontal scroll handle any total overflow,
109904
+ same as every other group.
109069
109905
  -->
109070
109906
  <section
109071
- class="relative flex max-w-[420px] shrink items-start gap-1 overflow-hidden pb-3"
109907
+ class="relative flex max-w-[420px] shrink-0 items-start gap-1 overflow-hidden pb-3"
109072
109908
  [attr.aria-label]="'pptx.animation.motionPath' | translate"
109073
109909
  >
109074
109910
  <pptx-ribbon-motion-path-gallery
@@ -112521,7 +113357,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
112521
113357
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
112522
113358
 
112523
113359
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
112524
- const PPTX_ANGULAR_VIEWER_VERSION = "3.1.0";
113360
+ const PPTX_ANGULAR_VIEWER_VERSION = "3.2.0";
112525
113361
 
112526
113362
  /**
112527
113363
  * account-page.component.ts: File > Account content.
@@ -112705,7 +113541,6 @@ const CARD_ICONS = {
112705
113541
  saveAsPptx: 'P',
112706
113542
  saveAsPpsx: '▶',
112707
113543
  saveAsPptm: 'M',
112708
- package: '□',
112709
113544
  pdf: 'PDF',
112710
113545
  png: 'PNG',
112711
113546
  video: '▶',
@@ -112714,7 +113549,6 @@ const CARD_ICONS = {
112714
113549
  copyImage: '▣',
112715
113550
  print: '▧',
112716
113551
  share: '◇',
112717
- sharePackage: '□',
112718
113552
  };
112719
113553
  /**
112720
113554
  * Pure, testable filter: the main (non-footer) backstage nav entries visible
@@ -112738,6 +113572,9 @@ class RibbonFileSectionComponent {
112738
113572
  /** Toolbar buttons the host wants hidden (drops the Export nav entry/page). */
112739
113573
  this.hiddenActions = input([], /* @ts-ignore */
112740
113574
  ...(ngDevMode ? [{ debugName: "hiddenActions" }] : /* istanbul ignore next */ []));
113575
+ /** File > Options > Advanced > "Quickly access this number of Recent Documents". */
113576
+ this.recentPresentationsCount = input(undefined, /* @ts-ignore */
113577
+ ...(ngDevMode ? [{ debugName: "recentPresentationsCount" }] : /* istanbul ignore next */ []));
112741
113578
  /** Optional sign-in hook point for the Account page. Absent/disabled by default. */
112742
113579
  this.accountAuth = input(undefined, /* @ts-ignore */
112743
113580
  ...(ngDevMode ? [{ debugName: "accountAuth" }] : /* istanbul ignore next */ []));
@@ -112748,7 +113585,6 @@ class RibbonFileSectionComponent {
112748
113585
  this.save = output();
112749
113586
  this.savePpsx = output();
112750
113587
  this.savePptm = output();
112751
- this.packageForSharing = output();
112752
113588
  this.exportPng = output();
112753
113589
  this.exportPdf = output();
112754
113590
  this.exportGif = output();
@@ -112796,7 +113632,7 @@ class RibbonFileSectionComponent {
112796
113632
  this.size = formatBackstageSize;
112797
113633
  this.actions = computed(() => this.pageActions(this.page()), /* @ts-ignore */
112798
113634
  ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
112799
- void (async () => this.recent.set(await listBackstageRecentFiles(this.t)))();
113635
+ void (async () => this.recent.set(await listBackstageRecentFiles(this.t, this.recentPresentationsCount())))();
112800
113636
  }
112801
113637
  date(timestamp) {
112802
113638
  return formatBackstageDate(timestamp, Date.now(), this.t);
@@ -112844,7 +113680,6 @@ class RibbonFileSectionComponent {
112844
113680
  saveAsPptx: this.save,
112845
113681
  saveAsPpsx: this.savePpsx,
112846
113682
  saveAsPptm: this.savePptm,
112847
- package: this.packageForSharing,
112848
113683
  pdf: this.exportPdf,
112849
113684
  png: this.exportPng,
112850
113685
  video: this.exportVideo,
@@ -112853,7 +113688,6 @@ class RibbonFileSectionComponent {
112853
113688
  copyImage: this.copySlideAsImage,
112854
113689
  print: this.print,
112855
113690
  share: this.share,
112856
- sharePackage: this.packageForSharing,
112857
113691
  };
112858
113692
  return backstageCardsFor(page)
112859
113693
  .filter((card) => card.id !== 'saveAsPptm' || this.hasMacros())
@@ -112865,12 +113699,12 @@ class RibbonFileSectionComponent {
112865
113699
  }));
112866
113700
  }
112867
113701
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonFileSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
112868
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonFileSectionComponent, isStandalone: true, selector: "pptx-ribbon-file-section", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", createPresentation: "createPresentation", openFile: "openFile", openRecentFile: "openRecentFile", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", print: "print", info: "info", signatures: "signatures", replace: "replace", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", share: "share", options: "options" }, host: { classAttribute: "contents" }, ngImport: i0, template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"], dependencies: [{ kind: "component", type: BackstageNavIconComponent, selector: "pptx-backstage-nav-icon", inputs: ["page"] }, { kind: "component", type: AccountPageComponent, selector: "pptx-account-page", inputs: ["accountAuth"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
113702
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonFileSectionComponent, isStandalone: true, selector: "pptx-ribbon-file-section", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, recentPresentationsCount: { classPropertyName: "recentPresentationsCount", publicName: "recentPresentationsCount", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", createPresentation: "createPresentation", openFile: "openFile", openRecentFile: "openRecentFile", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", print: "print", info: "info", signatures: "signatures", replace: "replace", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", share: "share", options: "options" }, host: { classAttribute: "contents" }, ngImport: i0, template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"], dependencies: [{ kind: "component", type: BackstageNavIconComponent, selector: "pptx-backstage-nav-icon", inputs: ["page"] }, { kind: "component", type: AccountPageComponent, selector: "pptx-account-page", inputs: ["accountAuth"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
112869
113703
  }
112870
113704
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonFileSectionComponent, decorators: [{
112871
113705
  type: Component,
112872
113706
  args: [{ selector: 'pptx-ribbon-file-section', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'contents' }, imports: [BackstageNavIconComponent, AccountPageComponent, TranslatePipe], template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"] }]
112873
- }], ctorParameters: () => [], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], print: [{ type: i0.Output, args: ["print"] }], info: [{ type: i0.Output, args: ["info"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], replace: [{ type: i0.Output, args: ["replace"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], share: [{ type: i0.Output, args: ["share"] }], options: [{ type: i0.Output, args: ["options"] }] } });
113707
+ }], ctorParameters: () => [], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], recentPresentationsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "recentPresentationsCount", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], print: [{ type: i0.Output, args: ["print"] }], info: [{ type: i0.Output, args: ["info"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], replace: [{ type: i0.Output, args: ["replace"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], share: [{ type: i0.Output, args: ["share"] }], options: [{ type: i0.Output, args: ["options"] }] } });
112874
113708
 
112875
113709
  /**
112876
113710
  * ribbon-font-controls.component.ts: the ribbon's reusable Font control group
@@ -114682,14 +115516,19 @@ class HeaderFooterRibbonButtonComponent {
114682
115516
  }
114683
115517
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HeaderFooterRibbonButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
114684
115518
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.3", type: HeaderFooterRibbonButtonComponent, isStandalone: true, selector: "pptx-header-footer-ribbon-button", ngImport: i0, template: `
115519
+ <!-- pptx-rb-pill, not pptx-rb-gb: this button is standalone (not
115520
+ inside a .pptx-rb-grp), so it needs its own rounded/bg-muted
115521
+ chrome rather than the border-r/no-background style meant for a
115522
+ group member. No icon either, matching React/Vue's plain-text
115523
+ Header & Footer pill. -->
114685
115524
  <button
114686
115525
  type="button"
114687
- class="pptx-rb-gb"
115526
+ class="pptx-rb-pill"
114688
115527
  (click)="dialogs.showHeaderFooter.set(true)"
114689
115528
  [title]="'pptx.headerFooter.title' | translate"
114690
115529
  [attr.aria-label]="'pptx.headerFooter.title' | translate"
114691
115530
  >
114692
- <span aria-hidden="true">#</span> {{ 'pptx.headerFooter.title' | translate }}
115531
+ {{ 'pptx.headerFooter.title' | translate }}
114693
115532
  </button>
114694
115533
  `, isInline: true, dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
114695
115534
  }
@@ -114701,14 +115540,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
114701
115540
  imports: [TranslatePipe],
114702
115541
  changeDetection: ChangeDetectionStrategy.OnPush,
114703
115542
  template: `
115543
+ <!-- pptx-rb-pill, not pptx-rb-gb: this button is standalone (not
115544
+ inside a .pptx-rb-grp), so it needs its own rounded/bg-muted
115545
+ chrome rather than the border-r/no-background style meant for a
115546
+ group member. No icon either, matching React/Vue's plain-text
115547
+ Header & Footer pill. -->
114704
115548
  <button
114705
115549
  type="button"
114706
- class="pptx-rb-gb"
115550
+ class="pptx-rb-pill"
114707
115551
  (click)="dialogs.showHeaderFooter.set(true)"
114708
115552
  [title]="'pptx.headerFooter.title' | translate"
114709
115553
  [attr.aria-label]="'pptx.headerFooter.title' | translate"
114710
115554
  >
114711
- <span aria-hidden="true">#</span> {{ 'pptx.headerFooter.title' | translate }}
115555
+ {{ 'pptx.headerFooter.title' | translate }}
114712
115556
  </button>
114713
115557
  `,
114714
115558
  }]
@@ -115749,7 +116593,6 @@ class RibbonContentComponent {
115749
116593
  this.save = output();
115750
116594
  this.savePpsx = output();
115751
116595
  this.savePptm = output();
115752
- this.packageForSharing = output();
115753
116596
  this.signatures = output();
115754
116597
  this.info = output();
115755
116598
  this.print = output();
@@ -115783,7 +116626,7 @@ class RibbonContentComponent {
115783
116626
  ...(ngDevMode ? [{ debugName: "newShapeType" }] : /* istanbul ignore next */ []));
115784
116627
  }
115785
116628
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
115786
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonContentComponent, isStandalone: true, selector: "pptx-ribbon-content", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", find: "find", share: "share", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", signatures: "signatures", info: "info", print: "print", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", openSmartArtDialog: "openSmartArtDialog", openEquationDialog: "openEquationDialog", openTemplateGallery: "openTemplateGallery", link: "link", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openSettings: "openSettings" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
116629
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonContentComponent, isStandalone: true, selector: "pptx-ribbon-content", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", find: "find", share: "share", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", signatures: "signatures", info: "info", print: "print", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", openSmartArtDialog: "openSmartArtDialog", openEquationDialog: "openEquationDialog", openTemplateGallery: "openTemplateGallery", link: "link", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openSettings: "openSettings" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
115787
116630
  @switch (activeTab()) {
115788
116631
  @case ('file') {
115789
116632
  <pptx-ribbon-file-section
@@ -115798,7 +116641,6 @@ class RibbonContentComponent {
115798
116641
  (save)="save.emit()"
115799
116642
  (savePpsx)="savePpsx.emit()"
115800
116643
  (savePptm)="savePptm.emit()"
115801
- (packageForSharing)="packageForSharing.emit()"
115802
116644
  (exportPng)="exportPng.emit()"
115803
116645
  (exportPdf)="exportPdf.emit()"
115804
116646
  (exportGif)="exportGif.emit()"
@@ -115883,7 +116725,7 @@ class RibbonContentComponent {
115883
116725
  />
115884
116726
  }
115885
116727
  }
115886
- `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "packageForSharing", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
116728
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "recentPresentationsCount", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
115887
116729
  }
115888
116730
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonContentComponent, decorators: [{
115889
116731
  type: Component,
@@ -115916,7 +116758,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
115916
116758
  (save)="save.emit()"
115917
116759
  (savePpsx)="savePpsx.emit()"
115918
116760
  (savePptm)="savePptm.emit()"
115919
- (packageForSharing)="packageForSharing.emit()"
115920
116761
  (exportPng)="exportPng.emit()"
115921
116762
  (exportPdf)="exportPdf.emit()"
115922
116763
  (exportGif)="exportGif.emit()"
@@ -116003,7 +116844,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
116003
116844
  }
116004
116845
  `,
116005
116846
  }]
116006
- }], propDecorators: { activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], selectTab: [{ type: i0.Output, args: ["selectTab"] }], find: [{ type: i0.Output, args: ["find"] }], share: [{ type: i0.Output, args: ["share"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], link: [{ type: i0.Output, args: ["link"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
116847
+ }], propDecorators: { activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], selectTab: [{ type: i0.Output, args: ["selectTab"] }], find: [{ type: i0.Output, args: ["find"] }], share: [{ type: i0.Output, args: ["share"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], link: [{ type: i0.Output, args: ["link"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
116007
116848
 
116008
116849
  /**
116009
116850
  * ribbon-primary-row.component.ts: the quick-access (top) row of the editor
@@ -116592,6 +117433,14 @@ class RibbonTabListComponent {
116592
117433
  this.tra = TAB_ROW_ACTION_CLASSES;
116593
117434
  this.visibleTabs = computed(() => filterVisibleTabs(TOOLBAR_TABS, this.hiddenActions()), /* @ts-ignore */
116594
117435
  ...(ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []));
117436
+ this.translate = inject(TranslateService);
117437
+ /** Optional so the tab strip renders outside a full viewer host too. */
117438
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
117439
+ }
117440
+ /** ScreenTip-styled tab tooltip (null suppresses the title attribute). */
117441
+ tabTip(labelKey) {
117442
+ const label = this.translate.instant(labelKey);
117443
+ return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
116595
117444
  }
116596
117445
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonTabListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
116597
117446
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonTabListComponent, isStandalone: true, selector: "pptx-ribbon-tab-list", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, ribbonExpanded: { classPropertyName: "ribbonExpanded", publicName: "ribbonExpanded", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", record: "record", share: "share", toggleRibbonExpanded: "toggleRibbonExpanded" }, ngImport: i0, template: `
@@ -116605,6 +117454,7 @@ class RibbonTabListComponent {
116605
117454
  type="button"
116606
117455
  role="tab"
116607
117456
  [attr.aria-selected]="activeTab() === t.id"
117457
+ [title]="tabTip(t.labelKey)"
116608
117458
  (click)="selectTab.emit(t.id)"
116609
117459
  class="relative whitespace-nowrap px-3.5 py-2 text-[12px] font-medium transition-colors"
116610
117460
  [ngClass]="
@@ -116709,6 +117559,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
116709
117559
  type="button"
116710
117560
  role="tab"
116711
117561
  [attr.aria-selected]="activeTab() === t.id"
117562
+ [title]="tabTip(t.labelKey)"
116712
117563
  (click)="selectTab.emit(t.id)"
116713
117564
  class="relative whitespace-nowrap px-3.5 py-2 text-[12px] font-medium transition-colors"
116714
117565
  [ngClass]="
@@ -116914,7 +117765,6 @@ class RibbonComponent {
116914
117765
  this.save = output();
116915
117766
  this.savePpsx = output();
116916
117767
  this.savePptm = output();
116917
- this.packageForSharing = output();
116918
117768
  /** Emitted when the user toggles the slides panel from the top bar. */
116919
117769
  this.toggleSidebar = output();
116920
117770
  /** Emitted when the user clicks the AI assistant Sparkles toggle. */
@@ -117021,7 +117871,7 @@ class RibbonComponent {
117021
117871
  this.spellCheckChange.emit(enabled);
117022
117872
  }
117023
117873
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
117024
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: RibbonComponent, isStandalone: true, selector: "pptx-ribbon", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, zoomPercent: { classPropertyName: "zoomPercent", publicName: "zoomPercent", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, eyedropperActive: { classPropertyName: "eyedropperActive", publicName: "eyedropperActive", isSignal: true, isRequired: false, transformFunction: null }, themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, inspectorOpen: { classPropertyName: "inspectorOpen", publicName: "inspectorOpen", isSignal: true, isRequired: false, transformFunction: null }, commentsOpen: { classPropertyName: "commentsOpen", publicName: "commentsOpen", isSignal: true, isRequired: false, transformFunction: null }, commentCount: { classPropertyName: "commentCount", publicName: "commentCount", isSignal: true, isRequired: false, transformFunction: null }, findOpen: { classPropertyName: "findOpen", publicName: "findOpen", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, spellCheckEnabled: { classPropertyName: "spellCheckEnabled", publicName: "spellCheckEnabled", isSignal: true, isRequired: false, transformFunction: null }, showSubtitles: { classPropertyName: "showSubtitles", publicName: "showSubtitles", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, activeSlideHidden: { classPropertyName: "activeSlideHidden", publicName: "activeSlideHidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", zoomIn: "zoomIn", zoomOut: "zoomOut", zoomReset: "zoomReset", find: "find", present: "present", presenter: "presenter", record: "record", presentFromBeginning: "presentFromBeginning", rehearseTimings: "rehearseTimings", toggleSubtitles: "toggleSubtitles", openSubtitleSettings: "openSubtitleSettings", recordFromBeginning: "recordFromBeginning", recordFromCurrent: "recordFromCurrent", spellCheckChange: "spellCheckChange", share: "share", broadcast: "broadcast", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", toggleSidebar: "toggleSidebar", toggleAiPanel: "toggleAiPanel", signatures: "signatures", info: "info", print: "print", comments: "comments", a11y: "a11y", shortcuts: "shortcuts", versionHistory: "versionHistory", passwordProtection: "passwordProtection", fontEmbedding: "fontEmbedding", link: "link", openSorter: "openSorter", openReadingView: "openReadingView", openOutlineView: "openOutlineView", openMasterView: "openMasterView", toggleNotes: "toggleNotes", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", toggleInspector: "toggleInspector", drawToolChange: "drawToolChange", toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleGrid: "toggleGrid", toggleRulers: "toggleRulers", toggleGuides: "toggleGuides", toggleSelectionPane: "toggleSelectionPane", openCustomShows: "openCustomShows", toggleSnapToGrid: "toggleSnapToGrid", toggleSnapToShape: "toggleSnapToShape", addGuide: "addGuide", zoomToFit: "zoomToFit", toggleEyedropper: "toggleEyedropper", openSmartArtDialog: "openSmartArtDialog", openTemplateGallery: "openTemplateGallery", openEquationDialog: "openEquationDialog", openSetUpSlideShow: "openSetUpSlideShow", toggleHideSlide: "toggleHideSlide", openCompare: "openCompare", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openShortcuts: "openShortcuts", openSettings: "openSettings" }, ngImport: i0, template: `
117874
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: RibbonComponent, isStandalone: true, selector: "pptx-ribbon", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, zoomPercent: { classPropertyName: "zoomPercent", publicName: "zoomPercent", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, eyedropperActive: { classPropertyName: "eyedropperActive", publicName: "eyedropperActive", isSignal: true, isRequired: false, transformFunction: null }, themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, inspectorOpen: { classPropertyName: "inspectorOpen", publicName: "inspectorOpen", isSignal: true, isRequired: false, transformFunction: null }, commentsOpen: { classPropertyName: "commentsOpen", publicName: "commentsOpen", isSignal: true, isRequired: false, transformFunction: null }, commentCount: { classPropertyName: "commentCount", publicName: "commentCount", isSignal: true, isRequired: false, transformFunction: null }, findOpen: { classPropertyName: "findOpen", publicName: "findOpen", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, spellCheckEnabled: { classPropertyName: "spellCheckEnabled", publicName: "spellCheckEnabled", isSignal: true, isRequired: false, transformFunction: null }, showSubtitles: { classPropertyName: "showSubtitles", publicName: "showSubtitles", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, activeSlideHidden: { classPropertyName: "activeSlideHidden", publicName: "activeSlideHidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", zoomIn: "zoomIn", zoomOut: "zoomOut", zoomReset: "zoomReset", find: "find", present: "present", presenter: "presenter", record: "record", presentFromBeginning: "presentFromBeginning", rehearseTimings: "rehearseTimings", toggleSubtitles: "toggleSubtitles", openSubtitleSettings: "openSubtitleSettings", recordFromBeginning: "recordFromBeginning", recordFromCurrent: "recordFromCurrent", spellCheckChange: "spellCheckChange", share: "share", broadcast: "broadcast", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", toggleSidebar: "toggleSidebar", toggleAiPanel: "toggleAiPanel", signatures: "signatures", info: "info", print: "print", comments: "comments", a11y: "a11y", shortcuts: "shortcuts", versionHistory: "versionHistory", passwordProtection: "passwordProtection", fontEmbedding: "fontEmbedding", link: "link", openSorter: "openSorter", openReadingView: "openReadingView", openOutlineView: "openOutlineView", openMasterView: "openMasterView", toggleNotes: "toggleNotes", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", toggleInspector: "toggleInspector", drawToolChange: "drawToolChange", toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleGrid: "toggleGrid", toggleRulers: "toggleRulers", toggleGuides: "toggleGuides", toggleSelectionPane: "toggleSelectionPane", openCustomShows: "openCustomShows", toggleSnapToGrid: "toggleSnapToGrid", toggleSnapToShape: "toggleSnapToShape", addGuide: "addGuide", zoomToFit: "zoomToFit", toggleEyedropper: "toggleEyedropper", openSmartArtDialog: "openSmartArtDialog", openTemplateGallery: "openTemplateGallery", openEquationDialog: "openEquationDialog", openSetUpSlideShow: "openSetUpSlideShow", toggleHideSlide: "toggleHideSlide", openCompare: "openCompare", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openShortcuts: "openShortcuts", openSettings: "openSettings" }, ngImport: i0, template: `
117025
117875
  <div
117026
117876
  role="toolbar"
117027
117877
  [attr.aria-label]="'pptx.toolbar.presentationToolbarAria' | translate"
@@ -117077,7 +117927,7 @@ class RibbonComponent {
117077
117927
  />
117078
117928
 
117079
117929
  <div
117080
- class="flex min-h-[82px] flex-nowrap items-stretch gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117930
+ class="flex min-h-[82px] flex-nowrap items-center gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117081
117931
  [style.display]="ribbonExpanded() ? null : 'none'"
117082
117932
  >
117083
117933
  <pptx-ribbon-content
@@ -117101,7 +117951,6 @@ class RibbonComponent {
117101
117951
  (save)="save.emit()"
117102
117952
  (savePpsx)="savePpsx.emit()"
117103
117953
  (savePptm)="savePptm.emit()"
117104
- (packageForSharing)="packageForSharing.emit()"
117105
117954
  (signatures)="signatures.emit()"
117106
117955
  (info)="info.emit()"
117107
117956
  (print)="print.emit()"
@@ -117182,7 +118031,7 @@ class RibbonComponent {
117182
118031
  />
117183
118032
  </div>
117184
118033
  </div>
117185
- `, isInline: true, dependencies: [{ kind: "component", type: RibbonPrimaryRowComponent, selector: "pptx-ribbon-primary-row", inputs: ["slideCount", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "hiddenActions", "aiEnabled", "aiPanelOpen"], outputs: ["toggleSidebar", "toggleAiPanel", "toggleComments", "present", "presenter", "broadcast", "openCustomShows", "toggleInspector", "openSettings", "exportPng", "exportPdf", "exportGif", "exportVideo", "print", "info", "a11y", "save", "savePpsx", "savePptm", "copySlideAsImage", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "digitalSignatures"] }, { kind: "component", type: RibbonTabListComponent, selector: "pptx-ribbon-tab-list", inputs: ["activeTab", "canEdit", "collabConnected", "connectedCount", "ribbonExpanded", "hiddenActions"], outputs: ["selectTab", "record", "share", "toggleRibbonExpanded"] }, { kind: "component", type: RibbonContentComponent, selector: "pptx-ribbon-content", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["selectTab", "find", "share", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "signatures", "info", "print", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "openSmartArtDialog", "openEquationDialog", "openTemplateGallery", "link", "openPassword", "openFontEmbedding", "openVersionHistory", "openSettings"] }, { kind: "component", type: RibbonContentSecondaryComponent, selector: "pptx-ribbon-content-secondary", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "spellCheckEnabled", "showSubtitles", "activeSlideHidden", "hiddenActions"], outputs: ["present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "broadcast", "print", "comments", "a11y", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openShortcuts", "openSettings"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
118034
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonPrimaryRowComponent, selector: "pptx-ribbon-primary-row", inputs: ["slideCount", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "hiddenActions", "aiEnabled", "aiPanelOpen"], outputs: ["toggleSidebar", "toggleAiPanel", "toggleComments", "present", "presenter", "broadcast", "openCustomShows", "toggleInspector", "openSettings", "exportPng", "exportPdf", "exportGif", "exportVideo", "print", "info", "a11y", "save", "savePpsx", "savePptm", "copySlideAsImage", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "digitalSignatures"] }, { kind: "component", type: RibbonTabListComponent, selector: "pptx-ribbon-tab-list", inputs: ["activeTab", "canEdit", "collabConnected", "connectedCount", "ribbonExpanded", "hiddenActions"], outputs: ["selectTab", "record", "share", "toggleRibbonExpanded"] }, { kind: "component", type: RibbonContentComponent, selector: "pptx-ribbon-content", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["selectTab", "find", "share", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "signatures", "info", "print", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "openSmartArtDialog", "openEquationDialog", "openTemplateGallery", "link", "openPassword", "openFontEmbedding", "openVersionHistory", "openSettings"] }, { kind: "component", type: RibbonContentSecondaryComponent, selector: "pptx-ribbon-content-secondary", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "spellCheckEnabled", "showSubtitles", "activeSlideHidden", "hiddenActions"], outputs: ["present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "broadcast", "print", "comments", "a11y", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openShortcuts", "openSettings"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
117186
118035
  }
117187
118036
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonComponent, decorators: [{
117188
118037
  type: Component,
@@ -117253,7 +118102,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117253
118102
  />
117254
118103
 
117255
118104
  <div
117256
- class="flex min-h-[82px] flex-nowrap items-stretch gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
118105
+ class="flex min-h-[82px] flex-nowrap items-center gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117257
118106
  [style.display]="ribbonExpanded() ? null : 'none'"
117258
118107
  >
117259
118108
  <pptx-ribbon-content
@@ -117277,7 +118126,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117277
118126
  (save)="save.emit()"
117278
118127
  (savePpsx)="savePpsx.emit()"
117279
118128
  (savePptm)="savePptm.emit()"
117280
- (packageForSharing)="packageForSharing.emit()"
117281
118129
  (signatures)="signatures.emit()"
117282
118130
  (info)="info.emit()"
117283
118131
  (print)="print.emit()"
@@ -117360,7 +118208,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117360
118208
  </div>
117361
118209
  `,
117362
118210
  }]
117363
- }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], zoomPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomPercent", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], eyedropperActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropperActive", required: false }] }], themeGalleryOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeGalleryOpen", required: false }] }], sidebarCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarCollapsed", required: false }] }], inspectorOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "inspectorOpen", required: false }] }], commentsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentsOpen", required: false }] }], commentCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentCount", required: false }] }], findOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findOpen", required: false }] }], collabConnected: [{ type: i0.Input, args: [{ isSignal: true, alias: "collabConnected", required: false }] }], connectedCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedCount", required: false }] }], spellCheckEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheckEnabled", required: false }] }], showSubtitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubtitles", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], zoomIn: [{ type: i0.Output, args: ["zoomIn"] }], zoomOut: [{ type: i0.Output, args: ["zoomOut"] }], zoomReset: [{ type: i0.Output, args: ["zoomReset"] }], find: [{ type: i0.Output, args: ["find"] }], present: [{ type: i0.Output, args: ["present"] }], presenter: [{ type: i0.Output, args: ["presenter"] }], record: [{ type: i0.Output, args: ["record"] }], presentFromBeginning: [{ type: i0.Output, args: ["presentFromBeginning"] }], rehearseTimings: [{ type: i0.Output, args: ["rehearseTimings"] }], toggleSubtitles: [{ type: i0.Output, args: ["toggleSubtitles"] }], openSubtitleSettings: [{ type: i0.Output, args: ["openSubtitleSettings"] }], recordFromBeginning: [{ type: i0.Output, args: ["recordFromBeginning"] }], recordFromCurrent: [{ type: i0.Output, args: ["recordFromCurrent"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], share: [{ type: i0.Output, args: ["share"] }], broadcast: [{ type: i0.Output, args: ["broadcast"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], toggleSidebar: [{ type: i0.Output, args: ["toggleSidebar"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], comments: [{ type: i0.Output, args: ["comments"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], shortcuts: [{ type: i0.Output, args: ["shortcuts"] }], versionHistory: [{ type: i0.Output, args: ["versionHistory"] }], passwordProtection: [{ type: i0.Output, args: ["passwordProtection"] }], fontEmbedding: [{ type: i0.Output, args: ["fontEmbedding"] }], link: [{ type: i0.Output, args: ["link"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openReadingView: [{ type: i0.Output, args: ["openReadingView"] }], openOutlineView: [{ type: i0.Output, args: ["openOutlineView"] }], openMasterView: [{ type: i0.Output, args: ["openMasterView"] }], toggleNotes: [{ type: i0.Output, args: ["toggleNotes"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], toggleInspector: [{ type: i0.Output, args: ["toggleInspector"] }], drawToolChange: [{ type: i0.Output, args: ["drawToolChange"] }], toggleThemeGallery: [{ type: i0.Output, args: ["toggleThemeGallery"] }], editTheme: [{ type: i0.Output, args: ["editTheme"] }], openSlideSize: [{ type: i0.Output, args: ["openSlideSize"] }], toggleGrid: [{ type: i0.Output, args: ["toggleGrid"] }], toggleRulers: [{ type: i0.Output, args: ["toggleRulers"] }], toggleGuides: [{ type: i0.Output, args: ["toggleGuides"] }], toggleSelectionPane: [{ type: i0.Output, args: ["toggleSelectionPane"] }], openCustomShows: [{ type: i0.Output, args: ["openCustomShows"] }], toggleSnapToGrid: [{ type: i0.Output, args: ["toggleSnapToGrid"] }], toggleSnapToShape: [{ type: i0.Output, args: ["toggleSnapToShape"] }], addGuide: [{ type: i0.Output, args: ["addGuide"] }], zoomToFit: [{ type: i0.Output, args: ["zoomToFit"] }], toggleEyedropper: [{ type: i0.Output, args: ["toggleEyedropper"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openSetUpSlideShow: [{ type: i0.Output, args: ["openSetUpSlideShow"] }], toggleHideSlide: [{ type: i0.Output, args: ["toggleHideSlide"] }], activeSlideHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideHidden", required: false }] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openShortcuts: [{ type: i0.Output, args: ["openShortcuts"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
118211
+ }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], zoomPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomPercent", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], eyedropperActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropperActive", required: false }] }], themeGalleryOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeGalleryOpen", required: false }] }], sidebarCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarCollapsed", required: false }] }], inspectorOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "inspectorOpen", required: false }] }], commentsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentsOpen", required: false }] }], commentCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentCount", required: false }] }], findOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findOpen", required: false }] }], collabConnected: [{ type: i0.Input, args: [{ isSignal: true, alias: "collabConnected", required: false }] }], connectedCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedCount", required: false }] }], spellCheckEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheckEnabled", required: false }] }], showSubtitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubtitles", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], zoomIn: [{ type: i0.Output, args: ["zoomIn"] }], zoomOut: [{ type: i0.Output, args: ["zoomOut"] }], zoomReset: [{ type: i0.Output, args: ["zoomReset"] }], find: [{ type: i0.Output, args: ["find"] }], present: [{ type: i0.Output, args: ["present"] }], presenter: [{ type: i0.Output, args: ["presenter"] }], record: [{ type: i0.Output, args: ["record"] }], presentFromBeginning: [{ type: i0.Output, args: ["presentFromBeginning"] }], rehearseTimings: [{ type: i0.Output, args: ["rehearseTimings"] }], toggleSubtitles: [{ type: i0.Output, args: ["toggleSubtitles"] }], openSubtitleSettings: [{ type: i0.Output, args: ["openSubtitleSettings"] }], recordFromBeginning: [{ type: i0.Output, args: ["recordFromBeginning"] }], recordFromCurrent: [{ type: i0.Output, args: ["recordFromCurrent"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], share: [{ type: i0.Output, args: ["share"] }], broadcast: [{ type: i0.Output, args: ["broadcast"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], toggleSidebar: [{ type: i0.Output, args: ["toggleSidebar"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], comments: [{ type: i0.Output, args: ["comments"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], shortcuts: [{ type: i0.Output, args: ["shortcuts"] }], versionHistory: [{ type: i0.Output, args: ["versionHistory"] }], passwordProtection: [{ type: i0.Output, args: ["passwordProtection"] }], fontEmbedding: [{ type: i0.Output, args: ["fontEmbedding"] }], link: [{ type: i0.Output, args: ["link"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openReadingView: [{ type: i0.Output, args: ["openReadingView"] }], openOutlineView: [{ type: i0.Output, args: ["openOutlineView"] }], openMasterView: [{ type: i0.Output, args: ["openMasterView"] }], toggleNotes: [{ type: i0.Output, args: ["toggleNotes"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], toggleInspector: [{ type: i0.Output, args: ["toggleInspector"] }], drawToolChange: [{ type: i0.Output, args: ["drawToolChange"] }], toggleThemeGallery: [{ type: i0.Output, args: ["toggleThemeGallery"] }], editTheme: [{ type: i0.Output, args: ["editTheme"] }], openSlideSize: [{ type: i0.Output, args: ["openSlideSize"] }], toggleGrid: [{ type: i0.Output, args: ["toggleGrid"] }], toggleRulers: [{ type: i0.Output, args: ["toggleRulers"] }], toggleGuides: [{ type: i0.Output, args: ["toggleGuides"] }], toggleSelectionPane: [{ type: i0.Output, args: ["toggleSelectionPane"] }], openCustomShows: [{ type: i0.Output, args: ["openCustomShows"] }], toggleSnapToGrid: [{ type: i0.Output, args: ["toggleSnapToGrid"] }], toggleSnapToShape: [{ type: i0.Output, args: ["toggleSnapToShape"] }], addGuide: [{ type: i0.Output, args: ["addGuide"] }], zoomToFit: [{ type: i0.Output, args: ["zoomToFit"] }], toggleEyedropper: [{ type: i0.Output, args: ["toggleEyedropper"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openSetUpSlideShow: [{ type: i0.Output, args: ["openSetUpSlideShow"] }], toggleHideSlide: [{ type: i0.Output, args: ["toggleHideSlide"] }], activeSlideHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideHidden", required: false }] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openShortcuts: [{ type: i0.Output, args: ["openShortcuts"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
117364
118212
 
117365
118213
  /**
117366
118214
  * selection-pane-helpers.ts: pure display + rename logic behind
@@ -120201,9 +121049,9 @@ function addCategory(element) {
120201
121049
  * const updated = removeCategory(el, 2);
120202
121050
  * ```
120203
121051
  */
120204
- function removeCategory(element, catIndex) {
121052
+ function removeCategory(element, catIndex, followDataPoint = true) {
120205
121053
  const chartData = element.chartData;
120206
- const next = chartData && removeChartCategory(chartData, catIndex);
121054
+ const next = chartData && removeChartCategory(chartData, catIndex, followDataPoint);
120207
121055
  return next ? { ...element, chartData: next } : element;
120208
121056
  }
120209
121057
  // ---------------------------------------------------------------------------
@@ -122210,10 +123058,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
122210
123058
  * @module angular-viewer/chart-data-editor
122211
123059
  */
122212
123060
  class ChartDataEditorComponent {
123061
+ /**
123062
+ * File > Options > Advanced > "Properties follow chart data point for
123063
+ * current workbook". Falls back to PowerPoint's own default (`true`) when
123064
+ * the service is unavailable (standalone unit tests).
123065
+ */
123066
+ followDataPoint() {
123067
+ return this.viewerOpts?.options().advanced.chartPropertiesFollowDataPoint ?? true;
123068
+ }
122213
123069
  constructor() {
122214
123070
  this.translate = inject(TranslateService);
122215
123071
  /** Canvas <-> inspector chart-part selection bridge (viewer-scoped, optional). */
122216
123072
  this.partSelection = inject(ChartPartSelectionService, { optional: true });
123073
+ /** File > Options access (viewer-scoped, optional for standalone unit tests). */
123074
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
122217
123075
  this.host = inject(ElementRef);
122218
123076
  this.injector = inject(Injector);
122219
123077
  /** The chart element being edited. */
@@ -122328,10 +123186,10 @@ class ChartDataEditorComponent {
122328
123186
  if (last < 0) {
122329
123187
  return;
122330
123188
  }
122331
- this.elementChange.emit(removeCategory(this.element(), last));
123189
+ this.elementChange.emit(removeCategory(this.element(), last, this.followDataPoint()));
122332
123190
  }
122333
123191
  onRemoveCategory(catIndex) {
122334
- this.elementChange.emit(removeCategory(this.element(), catIndex));
123192
+ this.elementChange.emit(removeCategory(this.element(), catIndex, this.followDataPoint()));
122335
123193
  }
122336
123194
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ChartDataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
122337
123195
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ChartDataEditorComponent, isStandalone: true, selector: "pptx-chart-data-editor", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementChange: "elementChange" }, ngImport: i0, template: `
@@ -132810,7 +133668,7 @@ class SlideBackgroundCardComponent {
132810
133668
  }
132811
133669
  </section>
132812
133670
  }
132813
- `, isInline: true, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
133671
+ `, isInline: true, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;top:0;left:0;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
132814
133672
  }
132815
133673
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SlideBackgroundCardComponent, decorators: [{
132816
133674
  type: Component,
@@ -132923,7 +133781,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
132923
133781
  }
132924
133782
  </section>
132925
133783
  }
132926
- `, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"] }]
133784
+ `, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;top:0;left:0;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"] }]
132927
133785
  }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }] } });
132928
133786
 
132929
133787
  /**
@@ -134623,176 +135481,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
134623
135481
  }]
134624
135482
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], activeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeName", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], startCustomizing: [{ type: i0.Input, args: [{ isSignal: true, alias: "startCustomizing", required: false }] }], applyTheme: [{ type: i0.Output, args: ["applyTheme"] }], applyCustomTheme: [{ type: i0.Output, args: ["applyCustomTheme"] }], close: [{ type: i0.Output, args: ["close"] }] } });
134625
135483
 
134626
- /**
134627
- * quick-access-strip.component.ts: the Quick Access Toolbar strip driven by
134628
- * File > Options > Quick Access Toolbar.
134629
- *
134630
- * Renders the ordered {@link QUICK_ACCESS_COMMAND_CATALOG} commands from
134631
- * `options.quickAccess.commandIds` as icon buttons (optionally with labels),
134632
- * emitting the pressed command id; the host maps ids onto its existing
134633
- * handlers. Replaces the title bar's previously hardcoded Save/Undo/Redo
134634
- * trio, and is also rendered below the ribbon when the position option is
134635
- * `below`. Tooltips honour the ScreenTip style via {@link ViewerOptionsService}.
134636
- */
134637
- /** Resolve the configured command ids to renderable strip entries. */
134638
- function resolveQuickAccessItems(commandIds) {
134639
- const items = [];
134640
- for (const id of commandIds) {
134641
- const command = getQuickAccessCommand(id);
134642
- if (command) {
134643
- items.push({ id, icon: command.icon, labelKey: command.labelKey });
134644
- }
134645
- }
134646
- return items;
134647
- }
134648
- class QuickAccessStripComponent {
134649
- constructor() {
134650
- /** The live Quick Access options group (visibility is gated by the host). */
134651
- this.quickAccess = input.required(/* @ts-ignore */
134652
- ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
134653
- this.canUndo = input(false, /* @ts-ignore */
134654
- ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
134655
- this.canRedo = input(false, /* @ts-ignore */
134656
- ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
134657
- /** A configured command id was pressed. */
134658
- this.command = output();
134659
- this.translate = inject(TranslateService);
134660
- /** Optional so the strip renders outside a full viewer host too. */
134661
- this.viewerOpts = inject(ViewerOptionsService, { optional: true });
134662
- this.tb = TITLE_BAR_CLASSES;
134663
- this.items = computed(() => resolveQuickAccessItems(this.quickAccess().commandIds), /* @ts-ignore */
134664
- ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
134665
- }
134666
- label(item) {
134667
- return this.translate.instant(item.labelKey);
134668
- }
134669
- /** ScreenTip-styled tooltip (null suppresses the title attribute). */
134670
- tip(item) {
134671
- const label = this.label(item);
134672
- return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
134673
- }
134674
- isDisabled(id) {
134675
- if (id === 'undo') {
134676
- return !this.canUndo();
134677
- }
134678
- if (id === 'redo') {
134679
- return !this.canRedo();
134680
- }
134681
- return false;
134682
- }
134683
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
134684
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: QuickAccessStripComponent, isStandalone: true, selector: "pptx-quick-access-strip", inputs: { quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: true, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { command: "command" }, ngImport: i0, template: `
134685
- @for (item of items(); track item.id) {
134686
- <button
134687
- type="button"
134688
- [class]="tb.quickButton"
134689
- [disabled]="isDisabled(item.id)"
134690
- [attr.title]="tip(item)"
134691
- [attr.aria-label]="label(item)"
134692
- (click)="command.emit(item.id)"
134693
- >
134694
- @switch (item.icon) {
134695
- @case ('save') {
134696
- <svg lucideSave class="h-3.5 w-3.5"></svg>
134697
- }
134698
- @case ('undo') {
134699
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
134700
- }
134701
- @case ('redo') {
134702
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
134703
- }
134704
- @case ('play') {
134705
- <svg lucidePlay class="h-3.5 w-3.5"></svg>
134706
- }
134707
- @case ('printer') {
134708
- <svg lucidePrinter class="h-3.5 w-3.5"></svg>
134709
- }
134710
- @case ('fileDown') {
134711
- <svg lucideFileDown class="h-3.5 w-3.5"></svg>
134712
- }
134713
- @case ('plus') {
134714
- <svg lucidePlus class="h-3.5 w-3.5"></svg>
134715
- }
134716
- @case ('spellCheck') {
134717
- <svg lucideSearch class="h-3.5 w-3.5"></svg>
134718
- }
134719
- @case ('zoomIn') {
134720
- <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
134721
- }
134722
- @default {
134723
- <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
134724
- }
134725
- }
134726
- @if (quickAccess().showCommandLabels) {
134727
- <span class="pptx-ng-qat-label">{{ label(item) }}</span>
134728
- }
134729
- </button>
134730
- }
134731
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucidePlay, selector: "svg[lucidePlay]" }, { kind: "component", type: LucidePrinter, selector: "svg[lucidePrinter]" }, { kind: "component", type: LucideFileDown, selector: "svg[lucideFileDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "component", type: LucideZoomIn, selector: "svg[lucideZoomIn]" }, { kind: "component", type: LucideZoomOut, selector: "svg[lucideZoomOut]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134732
- }
134733
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, decorators: [{
134734
- type: Component,
134735
- args: [{ selector: 'pptx-quick-access-strip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
134736
- LucideSave,
134737
- LucideUndo,
134738
- LucideRedo,
134739
- LucidePlay,
134740
- LucidePrinter,
134741
- LucideFileDown,
134742
- LucidePlus,
134743
- LucideSearch,
134744
- LucideZoomIn,
134745
- LucideZoomOut,
134746
- ], template: `
134747
- @for (item of items(); track item.id) {
134748
- <button
134749
- type="button"
134750
- [class]="tb.quickButton"
134751
- [disabled]="isDisabled(item.id)"
134752
- [attr.title]="tip(item)"
134753
- [attr.aria-label]="label(item)"
134754
- (click)="command.emit(item.id)"
134755
- >
134756
- @switch (item.icon) {
134757
- @case ('save') {
134758
- <svg lucideSave class="h-3.5 w-3.5"></svg>
134759
- }
134760
- @case ('undo') {
134761
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
134762
- }
134763
- @case ('redo') {
134764
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
134765
- }
134766
- @case ('play') {
134767
- <svg lucidePlay class="h-3.5 w-3.5"></svg>
134768
- }
134769
- @case ('printer') {
134770
- <svg lucidePrinter class="h-3.5 w-3.5"></svg>
134771
- }
134772
- @case ('fileDown') {
134773
- <svg lucideFileDown class="h-3.5 w-3.5"></svg>
134774
- }
134775
- @case ('plus') {
134776
- <svg lucidePlus class="h-3.5 w-3.5"></svg>
134777
- }
134778
- @case ('spellCheck') {
134779
- <svg lucideSearch class="h-3.5 w-3.5"></svg>
134780
- }
134781
- @case ('zoomIn') {
134782
- <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
134783
- }
134784
- @default {
134785
- <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
134786
- }
134787
- }
134788
- @if (quickAccess().showCommandLabels) {
134789
- <span class="pptx-ng-qat-label">{{ label(item) }}</span>
134790
- }
134791
- </button>
134792
- }
134793
- `, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"] }]
134794
- }], propDecorators: { quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: true }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], command: [{ type: i0.Output, args: ["command"] }] } });
134795
-
134796
135484
  /**
134797
135485
  * title-bar-search.component.ts: the centred command-search box + results
134798
135486
  * dropdown of the editor title bar.
@@ -135045,6 +135733,23 @@ function narrowToExtraQuickAccess(options) {
135045
135733
  : [],
135046
135734
  };
135047
135735
  }
135736
+ /**
135737
+ * The below-ribbon strip's options, or `null` when nothing renders there:
135738
+ * hidden, position `above`, or no commands beyond the dedicated trio.
135739
+ *
135740
+ * Single source of truth for BOTH sides of the "below the ribbon" placement:
135741
+ * {@link PowerPointViewerComponent} renders the strip precisely when this is
135742
+ * non-null, and this component's own inline strip below suppresses itself
135743
+ * under the identical condition, so the two can never disagree about where
135744
+ * the configured commands show up.
135745
+ */
135746
+ function resolveBelowRibbonQuickAccess(options) {
135747
+ if (!options.visible || options.position !== 'below') {
135748
+ return null;
135749
+ }
135750
+ const narrowed = narrowToExtraQuickAccess(options);
135751
+ return narrowed.commandIds.length > 0 ? narrowed : null;
135752
+ }
135048
135753
  class TitleBarComponent {
135049
135754
  constructor() {
135050
135755
  /** Whether the deck is editable (gates the autosave/quick-access/search chrome). */
@@ -135100,6 +135805,13 @@ class TitleBarComponent {
135100
135805
  */
135101
135806
  this.extraQat = computed(() => narrowToExtraQuickAccess(this.qat()), /* @ts-ignore */
135102
135807
  ...(ngDevMode ? [{ debugName: "extraQat" }] : /* istanbul ignore next */ []));
135808
+ /**
135809
+ * Whether the below-ribbon strip is the one rendering the configured extra
135810
+ * commands right now, so this component's OWN inline strip stands down
135811
+ * instead of showing the same commands twice.
135812
+ */
135813
+ this.belowRibbonActive = computed(() => resolveBelowRibbonQuickAccess(this.qat()) !== null, /* @ts-ignore */
135814
+ ...(ngDevMode ? [{ debugName: "belowRibbonActive" }] : /* istanbul ignore next */ []));
135103
135815
  /** The i18n key for the save-location status text (next to the file name). */
135104
135816
  this.statusKey = computed(() => {
135105
135817
  const status = this.autosaveStatus();
@@ -135219,7 +135931,7 @@ class TitleBarComponent {
135219
135931
  <svg lucideRedo class="h-3.5 w-3.5"></svg>
135220
135932
  </button>
135221
135933
  }
135222
- @if (extraQat().commandIds.length > 0) {
135934
+ @if (extraQat().commandIds.length > 0 && !belowRibbonActive()) {
135223
135935
  <pptx-quick-access-strip
135224
135936
  [quickAccess]="extraQat()"
135225
135937
  (command)="onQuickCommand($event)"
@@ -135341,7 +136053,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
135341
136053
  <svg lucideRedo class="h-3.5 w-3.5"></svg>
135342
136054
  </button>
135343
136055
  }
135344
- @if (extraQat().commandIds.length > 0) {
136056
+ @if (extraQat().commandIds.length > 0 && !belowRibbonActive()) {
135345
136057
  <pptx-quick-access-strip
135346
136058
  [quickAccess]="extraQat()"
135347
136059
  (command)="onQuickCommand($event)"
@@ -140314,6 +141026,15 @@ class ViewerExtraDialogsComponent {
140314
141026
  this.editor = inject(EditorStateService);
140315
141027
  this.loader = inject(LoadContentService);
140316
141028
  this.fonts = inject(EmbeddedFontsService);
141029
+ this.smartArt3D = inject(SmartArt3DService);
141030
+ this.collab = inject(CollaborationService);
141031
+ /** Real runtime availability for the Options > Add-ins pane; see {@link resolveViewerExtraAddinStatus}. */
141032
+ this.addinStatus = computed(() => resolveViewerExtraAddinStatus({
141033
+ smartArt3dEnabled: this.smartArt3D.enabled(),
141034
+ disable3DRendering: this.viewerOpts.options().advanced.disable3DRendering,
141035
+ collaborationConnected: this.collab.connected(),
141036
+ }), /* @ts-ignore */
141037
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
140317
141038
  /** Distinct font families used across the editable deck. */
140318
141039
  this.usedFontFamilies = computed(() => collectUsedFontFamilies(this.editor.slides()), /* @ts-ignore */
140319
141040
  ...(ngDevMode ? [{ debugName: "usedFontFamilies" }] : /* istanbul ignore next */ []));
@@ -140478,6 +141199,7 @@ class ViewerExtraDialogsComponent {
140478
141199
  <pptx-settings-dialog
140479
141200
  [open]="svc.showSettings()"
140480
141201
  [options]="viewerOpts.options()"
141202
+ [addinStatus]="addinStatus()"
140481
141203
  [themeKey]="themeKey()"
140482
141204
  [availableThemes]="availableThemes()"
140483
141205
  [localeCode]="localeCode()"
@@ -140604,6 +141326,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
140604
141326
  <pptx-settings-dialog
140605
141327
  [open]="svc.showSettings()"
140606
141328
  [options]="viewerOpts.options()"
141329
+ [addinStatus]="addinStatus()"
140607
141330
  [themeKey]="themeKey()"
140608
141331
  [availableThemes]="availableThemes()"
140609
141332
  [localeCode]="localeCode()"
@@ -140665,6 +141388,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
140665
141388
  * the root element (app-wide sharing via `provideViewerTheme`).
140666
141389
  */
140667
141390
  class PowerPointViewerComponent {
141391
+ /** Lift Protected View's read-only lock for the current document (File > Options > Trust Center). */
141392
+ enableEditing() {
141393
+ this.protectedViewDismissed.set(true);
141394
+ }
140668
141395
  /** Flip the AutoSave preference, unless the host forbade autosave outright. */
140669
141396
  toggleAutosave() {
140670
141397
  if (this.autosaveActivation().toggleAvailable) {
@@ -140947,13 +141674,52 @@ class PowerPointViewerComponent {
140947
141674
  /** The `<main>` host; used to locate the live `.pptx-ng-canvas-stage`. */
140948
141675
  this.mainEl = viewChild('mainEl', /* @ts-ignore */
140949
141676
  ...(ngDevMode ? [{ debugName: "mainEl" }] : /* istanbul ignore next */ []));
141677
+ /**
141678
+ * Whether the CURRENT document's Protected View lock was lifted via the
141679
+ * banner's "Enable Editing" button this session. A document the host
141680
+ * opened read-only (`canEditInput()` false) never shows the banner, so
141681
+ * there is nothing to dismiss for it; reset to `false` whenever a new
141682
+ * presentation finishes loading (see the `loader.slides()` effect below),
141683
+ * so re-opening (or opening another) file starts protected again,
141684
+ * mirroring PowerPoint's own per-document banner.
141685
+ */
141686
+ this.protectedViewDismissed = signal(false, /* @ts-ignore */
141687
+ ...(ngDevMode ? [{ debugName: "protectedViewDismissed" }] : /* istanbul ignore next */ []));
140950
141688
  /**
140951
141689
  * Effective edit permission: the host's `canEdit` input gated by Trust
140952
141690
  * Center > "Open presentations in Protected View", which forces the deck
140953
- * read-only while enabled (File > Options wiring, mirrors PowerPoint).
141691
+ * read-only while enabled (File > Options wiring, mirrors PowerPoint),
141692
+ * unless the user has lifted it via `enableEditing()` for this document.
140954
141693
  */
140955
- this.canEdit = computed(() => this.canEditInput() && !this.viewerOpts.options().trust.openInProtectedView, /* @ts-ignore */
141694
+ this.canEdit = computed(() => this.canEditInput() &&
141695
+ (!this.viewerOpts.options().trust.openInProtectedView || this.protectedViewDismissed()), /* @ts-ignore */
140956
141696
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
141697
+ /** Whether the Protected View banner should show: host allows editing, the option still blocks it, and the user hasn't dismissed it yet. */
141698
+ this.protectedViewActive = computed(() => this.canEditInput() &&
141699
+ this.viewerOpts.options().trust.openInProtectedView &&
141700
+ !this.protectedViewDismissed(), /* @ts-ignore */
141701
+ ...(ngDevMode ? [{ debugName: "protectedViewActive" }] : /* istanbul ignore next */ []));
141702
+ /**
141703
+ * Toolbar/ribbon ids to hide: the host's own `hiddenActions` input, UNIONED
141704
+ * with File > Options > Customize Ribbon's `ribbon.hiddenTabIds` (see
141705
+ * {@link mergeHiddenActions}). Every chrome component downstream (ribbon,
141706
+ * title bar, mobile toolbar/menu, status bar) must see BOTH, or ticking a
141707
+ * tab off in Customize Ribbon changes what the pane displays without
141708
+ * changing what actually renders.
141709
+ */
141710
+ this.effectiveHiddenActions = computed(() => mergeHiddenActions(this.hiddenActions(), this.viewerOpts.options().ribbon.hiddenTabIds), /* @ts-ignore */
141711
+ ...(ngDevMode ? [{ debugName: "effectiveHiddenActions" }] : /* istanbul ignore next */ []));
141712
+ /**
141713
+ * File > Options > Quick Access Toolbar > Position "Below the Ribbon": the
141714
+ * configured commands beyond the dedicated Save/Undo/Redo trio (which stay
141715
+ * in the title bar regardless of position), or `null` when the strip has
141716
+ * nothing to show there (hidden, `above`, or no extra commands configured).
141717
+ * {@link TitleBarComponent} independently suppresses its own inline strip
141718
+ * under the identical {@link resolveBelowRibbonQuickAccess} condition, so
141719
+ * the commands render in exactly one place.
141720
+ */
141721
+ this.belowRibbonQuickAccess = computed(() => resolveBelowRibbonQuickAccess(this.viewerOpts.options().quickAccess), /* @ts-ignore */
141722
+ ...(ngDevMode ? [{ debugName: "belowRibbonQuickAccess" }] : /* istanbul ignore next */ []));
140957
141723
  this.activeSlideIndex = signal(0, /* @ts-ignore */
140958
141724
  ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
140959
141725
  /**
@@ -141349,35 +142115,31 @@ class PowerPointViewerComponent {
141349
142115
  this.viewerOpts.store.setOptions(next);
141350
142116
  }
141351
142117
  });
141352
- // Surface the `smartArt3D` opt-in to the element dispatcher via the
141353
- // viewer-scoped SmartArt3DService.
141354
- effect(() => {
141355
- this.smartArt3DSvc.enabled.set(this.smartArt3D());
141356
- });
141357
- // Surface the `surfaceChart3D` opt-in to the chart element view via the
141358
- // viewer-scoped SurfaceChart3DService.
141359
- effect(() => {
141360
- this.surfaceChart3DSvc.enabled.set(this.surfaceChart3D());
141361
- });
141362
- // Surface the `barChart3D` opt-in to the chart element view via the
141363
- // viewer-scoped BarChart3DService.
141364
- effect(() => {
141365
- this.barChart3DSvc.enabled.set(this.barChart3D());
141366
- });
141367
- // Surface the `lineChart3D` opt-in to the chart element view via the
141368
- // viewer-scoped LineChart3DService.
141369
- effect(() => {
141370
- this.lineChart3DSvc.enabled.set(this.lineChart3D());
141371
- });
141372
- // Surface the `areaChart3D` opt-in to the chart element view via the
141373
- // viewer-scoped AreaChart3DService.
142118
+ // Surface the six 3D opt-in props to their viewer-scoped services, each
142119
+ // ANDed with Options > Advanced > "Disable 3D rendering" (see
142120
+ // `resolve3DRenderingFlags`) so a viewer user can force flat 2D even in a
142121
+ // deck the host enabled 3D for. One effect (not six) so they all react to
142122
+ // the same options-changed signal read.
141374
142123
  effect(() => {
141375
- this.areaChart3DSvc.enabled.set(this.areaChart3D());
142124
+ const effective = resolve3DRenderingFlags({
142125
+ smartArt3D: this.smartArt3D(),
142126
+ surfaceChart3D: this.surfaceChart3D(),
142127
+ barChart3D: this.barChart3D(),
142128
+ lineChart3D: this.lineChart3D(),
142129
+ areaChart3D: this.areaChart3D(),
142130
+ pieChart3D: this.pieChart3D(),
142131
+ }, this.viewerOpts.options());
142132
+ this.smartArt3DSvc.enabled.set(effective.smartArt3D);
142133
+ this.surfaceChart3DSvc.enabled.set(effective.surfaceChart3D);
142134
+ this.barChart3DSvc.enabled.set(effective.barChart3D);
142135
+ this.lineChart3DSvc.enabled.set(effective.lineChart3D);
142136
+ this.areaChart3DSvc.enabled.set(effective.areaChart3D);
142137
+ this.pieChart3DSvc.enabled.set(effective.pieChart3D);
141376
142138
  });
141377
- // Surface the `pieChart3D` opt-in to the chart element view via the
141378
- // viewer-scoped PieChart3DService.
142139
+ // Advanced > "Maximum number of undos", re-applied live on every change
142140
+ // (not just at construction).
141379
142141
  effect(() => {
141380
- this.pieChart3DSvc.enabled.set(this.pieChart3D());
142142
+ this.editor.setHistoryDepth(this.viewerOpts.historyDepth());
141381
142143
  });
141382
142144
  // A new host `content` input supersedes any in-place picked file.
141383
142145
  effect(() => {
@@ -141401,6 +142163,9 @@ class PowerPointViewerComponent {
141401
142163
  untracked(() => {
141402
142164
  this.editor.setSlides(slides, this.loader.sections());
141403
142165
  this.activeSlideIndex.set(0);
142166
+ // A newly opened document is protected again even if the previous
142167
+ // one was unlocked via "Enable Editing" this session.
142168
+ this.protectedViewDismissed.set(false);
141404
142169
  // Adopt `p:showPr/p:custShow/@id`: a deck authored to open into a
141405
142170
  // named custom show must actually play it. A manual pick made later
141406
142171
  // overwrites this and wins until the next deck loads.
@@ -141551,6 +142316,7 @@ class PowerPointViewerComponent {
141551
142316
  slideCount: () => this.slideCount(),
141552
142317
  mergedSlides: () => this.mergedSlides(),
141553
142318
  resolveStage: () => this.stageElement(),
142319
+ imageExportScale: () => this.viewerOpts.imageExportScale(),
141554
142320
  });
141555
142321
  // Hand the find/replace controller a slide-navigation callback so a match
141556
142322
  // can scroll its slide into view.
@@ -141682,6 +142448,33 @@ class PowerPointViewerComponent {
141682
142448
  password: this.dialogs.presentationPassword(),
141683
142449
  passwordProtected: this.dialogs.isPasswordProtected(),
141684
142450
  }),
142451
+ afterSuccessfulSave: (format) => {
142452
+ this.viewerOpts.playFeedback();
142453
+ const filePath = this.filePath();
142454
+ if (format === 'pptx' && filePath && this.viewerOpts.shouldDiscardAutosaveOnSave()) {
142455
+ void deleteAutosaveSnapshot(filePath);
142456
+ }
142457
+ },
142458
+ });
142459
+ // File > Options > Save > "cache retention": a one-time sweep per mount is
142460
+ // enough, since a fresh snapshot only ever lands with a fresh timestamp.
142461
+ void (async () => {
142462
+ try {
142463
+ const snapshots = await listAutosaveSnapshots();
142464
+ const expired = resolveExpiredAutosaveSnapshots(snapshots, this.viewerOpts.options());
142465
+ await Promise.all(expired.map((key) => deleteAutosaveSnapshot(key)));
142466
+ }
142467
+ catch {
142468
+ // Best-effort background maintenance; a blocked IndexedDB skips it.
142469
+ }
142470
+ })();
142471
+ // File > Options > Save > "clear cache on close": also cover the viewer
142472
+ // being destroyed without a page unload (the `beforeunload` listener
142473
+ // above covers the tab actually closing/navigating away).
142474
+ this.destroyRef.onDestroy(() => {
142475
+ if (this.viewerOpts.shouldClearCacheOnClose()) {
142476
+ void this.viewerOpts.clearCache();
142477
+ }
141685
142478
  });
141686
142479
  // Hand the canvas-editing controller the accessors it alone needs from the
141687
142480
  // component (canEdit / active-slide / active-slide-index).
@@ -142397,9 +143190,16 @@ class PowerPointViewerComponent {
142397
143190
  this.activeDrawColor.set(state.color);
142398
143191
  this.activeDrawWidth.set(state.width);
142399
143192
  }
143193
+ /**
143194
+ * Comment/reply author: the host `authorName` input wins, otherwise fall
143195
+ * back to Options > General > "User name" before the generic "You".
143196
+ */
143197
+ commentAuthorName() {
143198
+ return this.authorName() || this.viewerOpts.options().general.userName || 'You';
143199
+ }
142400
143200
  /** Append a comment to the active slide (one history entry). */
142401
143201
  onCommentAdd(text) {
142402
- const next = addCommentToList(this.activeComments(), text, 'You');
143202
+ const next = addCommentToList(this.activeComments(), text, this.commentAuthorName());
142403
143203
  if (next) {
142404
143204
  this.editor.updateSlide(this.activeSlideIndex(), { comments: next });
142405
143205
  }
@@ -142420,7 +143220,7 @@ class PowerPointViewerComponent {
142420
143220
  }
142421
143221
  /** Append a threaded reply under a top-level comment on the active slide. */
142422
143222
  onCommentReply(event) {
142423
- const next = replyToCommentInList(this.activeComments(), event.parentId, event.text, 'You');
143223
+ const next = replyToCommentInList(this.activeComments(), event.parentId, event.text, this.commentAuthorName());
142424
143224
  if (next) {
142425
143225
  this.editor.updateSlide(this.activeSlideIndex(), { comments: next });
142426
143226
  }
@@ -142455,12 +143255,18 @@ class PowerPointViewerComponent {
142455
143255
  onKeyDown(event) {
142456
143256
  this.keyboard.handleKeyDown(event);
142457
143257
  }
143258
+ /** Options > Save > "clear cache on close": wipe recovery snapshots when the tab closes. */
143259
+ clearCacheOnUnload() {
143260
+ if (this.viewerOpts.shouldClearCacheOnClose()) {
143261
+ void this.viewerOpts.clearCache();
143262
+ }
143263
+ }
142458
143264
  /** Resolve the live slide-stage element within `<main>`. */
142459
143265
  stageElement() {
142460
143266
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
142461
143267
  }
142462
143268
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
142463
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
143269
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)", "window:beforeunload": "clearCacheOnUnload()" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
142464
143270
  <div
142465
143271
  class="pptx-ng-viewer"
142466
143272
  [ngClass]="rootClasses()"
@@ -142482,6 +143288,26 @@ class PowerPointViewerComponent {
142482
143288
  <pre class="pptx-ng-error-detail">{{ loader.error() }}</pre>
142483
143289
  </div>
142484
143290
  } @else {
143291
+ @if (protectedViewActive() && chromeVisible()) {
143292
+ <div
143293
+ class="pptx-ng-protected-view-banner flex items-center gap-3 border-b border-amber-700/30 bg-amber-900/20 px-4 py-2"
143294
+ role="status"
143295
+ >
143296
+ <span class="h-4 w-4 shrink-0 text-amber-400" aria-hidden="true">&#128274;</span>
143297
+ <p class="flex-1 text-xs text-amber-200">
143298
+ <strong>{{ 'pptx.security.protectedViewTitle' | translate }}</strong
143299
+ >:
143300
+ {{ 'pptx.options.trust.protectedViewInfo' | translate }}
143301
+ </p>
143302
+ <button
143303
+ type="button"
143304
+ class="shrink-0 rounded border border-amber-600/50 px-3 py-1 text-xs font-medium text-amber-100 transition-colors hover:bg-amber-700/30"
143305
+ (click)="enableEditing()"
143306
+ >
143307
+ {{ 'pptx.security.enableEditing' | translate }}
143308
+ </button>
143309
+ </div>
143310
+ }
142485
143311
  @if (!mobile.isMobile() && chromeVisible()) {
142486
143312
  <pptx-title-bar
142487
143313
  [canEdit]="canEdit()"
@@ -142494,7 +143320,7 @@ class PowerPointViewerComponent {
142494
143320
  [undoLabel]="editor.undoLabel()"
142495
143321
  [redoLabel]="editor.redoLabel()"
142496
143322
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
142497
- [hiddenActions]="hiddenActions()"
143323
+ [hiddenActions]="effectiveHiddenActions()"
142498
143324
  [quickAccess]="viewerOpts.options().quickAccess"
142499
143325
  (toggleAutosave)="toggleAutosave()"
142500
143326
  (save)="fileIO.saveAsPptx()"
@@ -142509,7 +143335,7 @@ class PowerPointViewerComponent {
142509
143335
  [slideCount]="slideCount()"
142510
143336
  [canEdit]="canEdit()"
142511
143337
  [selectedElement]="selectedElement()"
142512
- [hiddenActions]="hiddenActions()"
143338
+ [hiddenActions]="effectiveHiddenActions()"
142513
143339
  [zoomPercent]="zoomSvc.zoomPercent()"
142514
143340
  [formatPainterActive]="formatPainter.active()"
142515
143341
  [canActivateFormatPainter]="formatPainter.canActivate()"
@@ -142549,7 +143375,6 @@ class PowerPointViewerComponent {
142549
143375
  (save)="fileIO.saveAsPptx()"
142550
143376
  (savePpsx)="fileIO.saveAsPpsx()"
142551
143377
  (savePptm)="fileIO.saveAsPptm()"
142552
- (packageForSharing)="fileIO.packageForSharing()"
142553
143378
  (info)="docProperties.showProperties.set(true)"
142554
143379
  (print)="print.openDialog()"
142555
143380
  (comments)="inspectorPanel.togglePanel('comments')"
@@ -142612,6 +143437,20 @@ class PowerPointViewerComponent {
142612
143437
  [aiPanelOpen]="aiPanelOpen()"
142613
143438
  (toggleAiPanel)="aiPanelOpen.update((v) => !v)"
142614
143439
  />
143440
+
143441
+ @if (belowRibbonQuickAccess(); as belowQuickAccess) {
143442
+ <div
143443
+ class="flex items-center gap-0.5 border-b border-border/60 px-2 py-0.5"
143444
+ data-pptx-quick-access="below"
143445
+ >
143446
+ <pptx-quick-access-strip
143447
+ [quickAccess]="belowQuickAccess"
143448
+ [canUndo]="editor.canUndo()"
143449
+ [canRedo]="editor.canRedo()"
143450
+ (command)="onQuickAccessCommand($event)"
143451
+ />
143452
+ </div>
143453
+ }
142615
143454
  }
142616
143455
 
142617
143456
  @if (mobile.isMobile() && chromeVisible()) {
@@ -142623,7 +143462,7 @@ class PowerPointViewerComponent {
142623
143462
  [menuOpen]="mobileSheetSvc.mobileSheet() === 'menu'"
142624
143463
  [aiEnabled]="aiEnabled()"
142625
143464
  [aiPanelOpen]="aiPanelOpen()"
142626
- [hiddenActions]="hiddenActions()"
143465
+ [hiddenActions]="effectiveHiddenActions()"
142627
143466
  (toggleMenu)="
142628
143467
  mobileSheetSvc.mobileSheet.set(
142629
143468
  mobileSheetSvc.mobileSheet() === 'menu' ? null : 'menu'
@@ -142915,7 +143754,7 @@ class PowerPointViewerComponent {
142915
143754
  [zoomPercent]="zoomSvc.zoomPercent()"
142916
143755
  [sorterActive]="showSorter()"
142917
143756
  [presenting]="presentationMode.presenting()"
142918
- [hiddenActions]="hiddenActions()"
143757
+ [hiddenActions]="effectiveHiddenActions()"
142919
143758
  (toggleNotes)="mobileSheetSvc.toggleNotes()"
142920
143759
  (normalView)="showSorter.set(false)"
142921
143760
  (openSorter)="showSorter.set(true)"
@@ -143026,6 +143865,8 @@ class PowerPointViewerComponent {
143026
143865
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
143027
143866
  [sessionEnded]="audienceSessionEnded()"
143028
143867
  [endWithBlackSlide]="viewerOpts.options().advanced.slideShowEndWithBlackSlide"
143868
+ [showMenuOnRightClick]="viewerOpts.options().advanced.slideShowShowMenuOnRightClick"
143869
+ [showPopupToolbar]="viewerOpts.options().advanced.slideShowShowPopupToolbar"
143029
143870
  [presenterMode]="presentationMode.presentingPresenter()"
143030
143871
  (presenterViewToggle)="presentationMode.togglePresenterView()"
143031
143872
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
@@ -143176,7 +144017,14 @@ class PowerPointViewerComponent {
143176
144017
  <pptx-print-dialog
143177
144018
  [slides]="displaySlidesMut()"
143178
144019
  [activeSlideIndex]="activeSlideIndex()"
143179
- (print)="xport.onPrint($event)"
144020
+ [defaultSettings]="viewerOpts.printDefaults()"
144021
+ (print)="
144022
+ xport.onPrint(
144023
+ $event,
144024
+ viewerOpts.options().advanced.printHiddenSlides,
144025
+ viewerOpts.options().advanced.printHighQuality
144026
+ )
144027
+ "
143180
144028
  (cancel)="print.closeDialog()"
143181
144029
  />
143182
144030
  }
@@ -143265,7 +144113,7 @@ class PowerPointViewerComponent {
143265
144113
  [exporting]="xport.exporting()"
143266
144114
  [showNotes]="mobileSheetSvc.showNotes()"
143267
144115
  [canEdit]="canEdit()"
143268
- [hiddenActions]="hiddenActions()"
144116
+ [hiddenActions]="effectiveHiddenActions()"
143269
144117
  (closed)="mobileSheetSvc.mobileSheet.set(null)"
143270
144118
  (openFind)="findReplace.showFind.set(true)"
143271
144119
  (openSorter)="showSorter.set(true)"
@@ -143340,7 +144188,7 @@ class PowerPointViewerComponent {
143340
144188
  />
143341
144189
  }
143342
144190
  </div>
143343
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "presenterMode"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
144191
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides", "defaultSettings"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: QuickAccessStripComponent, selector: "pptx-quick-access-strip", inputs: ["quickAccess", "canUndo", "canRedo"], outputs: ["command"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
143344
144192
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] }); }
143345
144193
  }
143346
144194
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -143389,6 +144237,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143389
144237
  MasterViewCanvasComponent,
143390
144238
  MasterViewSidebarComponent,
143391
144239
  NotesPanelComponent,
144240
+ QuickAccessStripComponent,
143392
144241
  RibbonComponent,
143393
144242
  TitleBarComponent,
143394
144243
  ThemeGalleryComponent,
@@ -143424,6 +144273,26 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143424
144273
  <pre class="pptx-ng-error-detail">{{ loader.error() }}</pre>
143425
144274
  </div>
143426
144275
  } @else {
144276
+ @if (protectedViewActive() && chromeVisible()) {
144277
+ <div
144278
+ class="pptx-ng-protected-view-banner flex items-center gap-3 border-b border-amber-700/30 bg-amber-900/20 px-4 py-2"
144279
+ role="status"
144280
+ >
144281
+ <span class="h-4 w-4 shrink-0 text-amber-400" aria-hidden="true">&#128274;</span>
144282
+ <p class="flex-1 text-xs text-amber-200">
144283
+ <strong>{{ 'pptx.security.protectedViewTitle' | translate }}</strong
144284
+ >:
144285
+ {{ 'pptx.options.trust.protectedViewInfo' | translate }}
144286
+ </p>
144287
+ <button
144288
+ type="button"
144289
+ class="shrink-0 rounded border border-amber-600/50 px-3 py-1 text-xs font-medium text-amber-100 transition-colors hover:bg-amber-700/30"
144290
+ (click)="enableEditing()"
144291
+ >
144292
+ {{ 'pptx.security.enableEditing' | translate }}
144293
+ </button>
144294
+ </div>
144295
+ }
143427
144296
  @if (!mobile.isMobile() && chromeVisible()) {
143428
144297
  <pptx-title-bar
143429
144298
  [canEdit]="canEdit()"
@@ -143436,7 +144305,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143436
144305
  [undoLabel]="editor.undoLabel()"
143437
144306
  [redoLabel]="editor.redoLabel()"
143438
144307
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
143439
- [hiddenActions]="hiddenActions()"
144308
+ [hiddenActions]="effectiveHiddenActions()"
143440
144309
  [quickAccess]="viewerOpts.options().quickAccess"
143441
144310
  (toggleAutosave)="toggleAutosave()"
143442
144311
  (save)="fileIO.saveAsPptx()"
@@ -143451,7 +144320,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143451
144320
  [slideCount]="slideCount()"
143452
144321
  [canEdit]="canEdit()"
143453
144322
  [selectedElement]="selectedElement()"
143454
- [hiddenActions]="hiddenActions()"
144323
+ [hiddenActions]="effectiveHiddenActions()"
143455
144324
  [zoomPercent]="zoomSvc.zoomPercent()"
143456
144325
  [formatPainterActive]="formatPainter.active()"
143457
144326
  [canActivateFormatPainter]="formatPainter.canActivate()"
@@ -143491,7 +144360,6 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143491
144360
  (save)="fileIO.saveAsPptx()"
143492
144361
  (savePpsx)="fileIO.saveAsPpsx()"
143493
144362
  (savePptm)="fileIO.saveAsPptm()"
143494
- (packageForSharing)="fileIO.packageForSharing()"
143495
144363
  (info)="docProperties.showProperties.set(true)"
143496
144364
  (print)="print.openDialog()"
143497
144365
  (comments)="inspectorPanel.togglePanel('comments')"
@@ -143554,6 +144422,20 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143554
144422
  [aiPanelOpen]="aiPanelOpen()"
143555
144423
  (toggleAiPanel)="aiPanelOpen.update((v) => !v)"
143556
144424
  />
144425
+
144426
+ @if (belowRibbonQuickAccess(); as belowQuickAccess) {
144427
+ <div
144428
+ class="flex items-center gap-0.5 border-b border-border/60 px-2 py-0.5"
144429
+ data-pptx-quick-access="below"
144430
+ >
144431
+ <pptx-quick-access-strip
144432
+ [quickAccess]="belowQuickAccess"
144433
+ [canUndo]="editor.canUndo()"
144434
+ [canRedo]="editor.canRedo()"
144435
+ (command)="onQuickAccessCommand($event)"
144436
+ />
144437
+ </div>
144438
+ }
143557
144439
  }
143558
144440
 
143559
144441
  @if (mobile.isMobile() && chromeVisible()) {
@@ -143565,7 +144447,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143565
144447
  [menuOpen]="mobileSheetSvc.mobileSheet() === 'menu'"
143566
144448
  [aiEnabled]="aiEnabled()"
143567
144449
  [aiPanelOpen]="aiPanelOpen()"
143568
- [hiddenActions]="hiddenActions()"
144450
+ [hiddenActions]="effectiveHiddenActions()"
143569
144451
  (toggleMenu)="
143570
144452
  mobileSheetSvc.mobileSheet.set(
143571
144453
  mobileSheetSvc.mobileSheet() === 'menu' ? null : 'menu'
@@ -143857,7 +144739,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143857
144739
  [zoomPercent]="zoomSvc.zoomPercent()"
143858
144740
  [sorterActive]="showSorter()"
143859
144741
  [presenting]="presentationMode.presenting()"
143860
- [hiddenActions]="hiddenActions()"
144742
+ [hiddenActions]="effectiveHiddenActions()"
143861
144743
  (toggleNotes)="mobileSheetSvc.toggleNotes()"
143862
144744
  (normalView)="showSorter.set(false)"
143863
144745
  (openSorter)="showSorter.set(true)"
@@ -143968,6 +144850,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143968
144850
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
143969
144851
  [sessionEnded]="audienceSessionEnded()"
143970
144852
  [endWithBlackSlide]="viewerOpts.options().advanced.slideShowEndWithBlackSlide"
144853
+ [showMenuOnRightClick]="viewerOpts.options().advanced.slideShowShowMenuOnRightClick"
144854
+ [showPopupToolbar]="viewerOpts.options().advanced.slideShowShowPopupToolbar"
143971
144855
  [presenterMode]="presentationMode.presentingPresenter()"
143972
144856
  (presenterViewToggle)="presentationMode.togglePresenterView()"
143973
144857
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
@@ -144118,7 +145002,14 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144118
145002
  <pptx-print-dialog
144119
145003
  [slides]="displaySlidesMut()"
144120
145004
  [activeSlideIndex]="activeSlideIndex()"
144121
- (print)="xport.onPrint($event)"
145005
+ [defaultSettings]="viewerOpts.printDefaults()"
145006
+ (print)="
145007
+ xport.onPrint(
145008
+ $event,
145009
+ viewerOpts.options().advanced.printHiddenSlides,
145010
+ viewerOpts.options().advanced.printHighQuality
145011
+ )
145012
+ "
144122
145013
  (cancel)="print.closeDialog()"
144123
145014
  />
144124
145015
  }
@@ -144207,7 +145098,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144207
145098
  [exporting]="xport.exporting()"
144208
145099
  [showNotes]="mobileSheetSvc.showNotes()"
144209
145100
  [canEdit]="canEdit()"
144210
- [hiddenActions]="hiddenActions()"
145101
+ [hiddenActions]="effectiveHiddenActions()"
144211
145102
  (closed)="mobileSheetSvc.mobileSheet.set(null)"
144212
145103
  (openFind)="findReplace.showFind.set(true)"
144213
145104
  (openSorter)="showSorter.set(true)"
@@ -144287,6 +145178,9 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144287
145178
  }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEditInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], autosaveInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosave", required: false }] }], autosaveIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveIntervalMs", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], surfaceChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceChart3D", required: false }] }], barChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "barChart3D", required: false }] }], lineChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineChart3D", required: false }] }], areaChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaChart3D", required: false }] }], pieChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieChart3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], ai: [{ type: i0.Input, args: [{ isSignal: true, alias: "ai", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
144288
145179
  type: HostListener,
144289
145180
  args: ['document:keydown', ['$event']]
145181
+ }], clearCacheOnUnload: [{
145182
+ type: HostListener,
145183
+ args: ['window:beforeunload']
144290
145184
  }] } }) });
144291
145185
 
144292
145186
  /**
@@ -146585,4 +147479,4 @@ function cn(...values) {
146585
147479
  */
146586
147480
 
146587
147481
  export { ColorChangedImageComponent as $, AFTER_ANIMATION_VALUES as A, AnimationPanelComponent as B, AnimationPlaybackService as C, AutosaveRecoveryDialogComponent as D, AutosaveService as E, BroadcastDialogComponent as F, CHART_EDITOR_STYLES as G, CURSOR_PALETTE as H, CanvasFitService as I, ChartAxisOptionsComponent as J, ChartAxisStyleOptionsComponent as K, ChartComboTypeOptionsComponent as L, ChartDataEditorComponent as M, ChartDataLabelOptionsComponent as N, ChartDatapointMarkerOptionsComponent as O, ChartDatapointOptionsComponent as P, ChartDisplayOptionsComponent as Q, ChartElementViewComponent as R, ChartErrorBarOptionsComponent as S, ChartMarkerOptionsComponent as T, ChartPartSelectionService as U, ChartPrimitivesComponent as V, ChartRendererComponent as W, ChartTrendlineOptionsComponent as X, ChartTypeSelectorComponent as Y, CollaborationCursorsComponent as Z, CollaborationService as _, ALIGN_OPTIONS as a, KeepAnnotationsDialogComponent as a$, CommentMarkersOverlayComponent as a0, CommentsPanelComponent as a1, CommentsService as a2, ComparePanelComponent as a3, ConnectorRendererComponent as a4, ConnectorTextOverlayComponent as a5, CustomShowsComponent as a6, DEFAULT_BOUNDS as a7, DEFAULT_BROADCAST_SERVER_URL as a8, DEFAULT_CANVAS_HEIGHT as a9, ElementRendererComponent as aA, EmbeddedFontsService as aB, EncryptedFileDialogComponent as aC, EquationEditorDialogComponent as aD, EquationRendererComponent as aE, EquationTemplateGalleryComponent as aF, ExportProgressModalComponent as aG, ExportService as aH, FieldContextService as aI, FindBarComponent as aJ, FindReplaceBarComponent as aK, FollowModeBarComponent as aL, FontEmbeddingListComponent as aM, FontEmbeddingPanelComponent as aN, GALLERY_THEME_PRESETS as aO, GRIDLINE_COLOR$1 as aP, GradientPickerComponent as aQ, HANDOUT_OPTIONS as aR, HeaderFooterDialogComponent as aS, HyperlinkDialogComponent as aT, ImagePropertiesPanelComponent as aU, InkDrawingService as aV, InkRendererComponent as aW, InsertSmartArtDialogComponent as aX, InspectorPaneHeaderComponent as aY, InspectorPanelComponent as aZ, IsMobileService as a_, DEFAULT_CANVAS_WIDTH as aa, DEFAULT_COLOR_SCHEME as ab, DEFAULT_FILL_COLOR$1 as ac, DEFAULT_LAYOUT as ad, DEFAULT_PALETTE$1 as ae, DEFAULT_PATTERN_FILL_PRESET as af, DEFAULT_PRINT_SETTINGS as ag, DEFAULT_SLIDE_BACKGROUND as ah, DEFAULT_STROKE_COLOR as ai, DEFAULT_STYLE as aj, DEFAULT_TABLE_ROW_HEIGHT as ak, DEFAULT_TEXT_COLOR$2 as al, DEFAULT_VIEWER_PROFILE as am, DIRECTIONAL_PRESETS as an, DIRECTION_OPTIONS as ao, DocumentPropertiesCardComponent as ap, EMBEDDED_FONTS_STYLE_ID as aq, EMPHASIS_PRESETS as ar, ENTRANCE_PRESETS as as, TEMPLATES as at, EXIT_PRESETS as au, EditorContextMenuComponent as av, EditorHistory as aw, EditorStateService as ax, EditorToolbarComponent as ay, EffectsPanelComponent as az, ANIMATION_PRESET_CATEGORIES as b, RibbonDrawSectionComponent as b$, LOCALE_CATALOG as b0, LONG_PRESS_DURATION_MS as b1, LONG_PRESS_MOVE_TOLERANCE_PX as b2, LoadContentService as b3, LocalPresencePublisher as b4, MAX_ZOOM_SCALE as b5, MIN_ZOOM_SCALE as b6, MOTION_PATH_COLUMNS as b7, MediaPreviewComponent as b8, MediaPropertiesPanelComponent as b9, PresentToolbarAutoHide as bA, PresentationAnnotationOverlayComponent as bB, PresentationAnnotationsService as bC, PresentationOverlayComponent as bD, PresentationPropertiesPanelComponent as bE, PresentationSettingsCardComponent as bF, PresentationSubtitleBarComponent as bG, PresentationToolbarComponent as bH, PresentationTransitionOverlayComponent as bI, PresenterViewComponent as bJ, PresenterWindowService as bK, PrintDialogComponent as bL, PrintService as bM, PrintSettingsPanelComponent as bN, PropertiesDialogComponent as bO, REPEAT_MODE_OPTIONS as bP, RESIZE_HANDLES as bQ, RULER_FONT_SIZE as bR, RULER_THICKNESS as bS, ReadingViewOverlayComponent as bT, RemoteSelectionOverlayComponent as bU, RibbonAnimationGalleryComponent as bV, RibbonAnimationsSectionComponent as bW, RibbonArrangeSectionComponent as bX, RibbonColorPopoverComponent as bY, RibbonComponent as bZ, RibbonDesignSectionComponent as b_, MediaRendererComponent as ba, MediaTrimTimelineComponent as bb, MobileBottomBarComponent as bc, MobileMenuSheetComponent as bd, MobilePresenterViewComponent as be, MobileSheetComponent as bf, MobileSlidesSheetComponent as bg, MobileToolbarComponent as bh, ModalDialogComponent as bi, Model3DRendererComponent as bj, NotesHandoutCardComponent as bk, NotesPanelComponent as bl, NotesToolbarComponent as bm, OleRendererComponent as bn, OutlineViewOverlayComponent as bo, POWER_POINT_VIEWER_PROVIDERS as bp, PPTX_OPEN_ACCEPT as bq, PRESENTATION_OPEN_EXTENSIONS as br, PRESENTER_CHANNEL_NAME as bs, PRESENTER_MSG_ORIGIN as bt, PRESENTER_TIMER_SEGMENT_MS as bu, PX_PER_CM as bv, PX_PER_INCH as bw, PasswordProtectionDialogComponent as bx, PasswordStrengthMeterComponent as by, PowerPointViewerComponent as bz, AUDIENCE_HASH as c, THEME_CATALOG as c$, RibbonDrawingGroupComponent as c0, RibbonEditingSectionComponent as c1, RibbonFileSectionComponent as c2, RibbonFontControlsComponent as c3, RibbonHomeSectionComponent as c4, RibbonHyperlinkButtonComponent as c5, RibbonInsertFieldsComponent as c6, RibbonInsertSectionComponent as c7, RibbonMotionPathGalleryComponent as c8, RibbonParagraphControlsComponent as c9, ShortcutPanelComponent as cA, ShowOptionsFieldsetComponent as cB, ShowSlidesFieldsetComponent as cC, SignatureStrippedDialogComponent as cD, SignaturesPanelComponent as cE, SignaturesService as cF, SlideBackgroundCardComponent as cG, SlideCanvasComponent as cH, SlideDefaultInspectorComponent as cI, SlideDiffChangesComponent as cJ, SlideDiffRowComponent as cK, SlideDiffThumbnailsComponent as cL, SlideSizeCardComponent as cM, SlideSorterOverlayComponent as cN, SlideThemeOverridePanelComponent as cO, SlideTransitionCardComponent as cP, SlidesPanelComponent as cQ, SmartArt3DRendererComponent as cR, SmartArt3DService as cS, SmartArtPreviewComponent as cT, SmartArtPropertiesComponent as cU, SmartArtRendererComponent as cV, StatusBarComponent as cW, TABLE_STRUCTURE_TOGGLES as cX, TEXT_3D_BOTTOM_BEVEL_KEYS as cY, TEXT_3D_TOP_BEVEL_KEYS as cZ, TEXT_DIRECTION_OPTIONS$1 as c_, RibbonPrimaryRowComponent as ca, RibbonReviewSectionComponent as cb, RibbonShapeExtrasComponent as cc, RibbonSlideshowSectionComponent as cd, RibbonTransitionsSectionComponent as ce, RibbonViewSectionComponent as cf, RulerGuidesService as cg, SEQUENCE_OPTIONS as ch, SEVERITY_GROUPS as ci, SEVERITY_LABELS as cj, SHORTCUT_REFERENCE_ITEMS as ck, SLIDE_TRANSITION_KEYFRAMES as cl, DEFAULT_PALETTE as cm, PALETTES$1 as cn, SMART_ART_COLOR_SCHEMES as co, SMART_ART_STYLE_OPTIONS as cp, SUB_ITEM_LABEL as cq, SVG_WARP_PRESETS as cr, SWIPE_MAX_VERTICAL_PX as cs, SWIPE_THRESHOLD_PX as ct, SelectionPaneComponent as cu, SetUpSlideShowDialogComponent as cv, SettingsAppearanceTabComponent as cw, SettingsDialogComponent as cx, SettingsLanguageTabComponent as cy, ShareDialogComponent as cz, AUDIENCE_NONCE_KEY as d, applyAcceptedDiff as d$, TIMING_CURVE_OPTIONS as d0, TRIGGER_OPTIONS as d1, TYPE_LABELS as d2, TableCellAdvancedFillComponent as d3, TableCellFormattingComponent as d4, TableDataEditorComponent as d5, TablePropertiesComponent as d6, TableRendererComponent as d7, TableResizeOverlayComponent as d8, TableSelectionService as d9, ViewerFormatPainterService as dA, ViewerInspectorPanelService as dB, ViewerKeyboardService as dC, ViewerMobileSheetService as dD, ViewerPresentationModeService as dE, ViewerThemeGalleryService as dF, ViewerTouchGesturesService as dG, ViewerZoomService as dH, WEBM_MIME_CANDIDATES as dI, WriteBackScheduler as dJ, ZERO_LINE_COLOR as dK, ZoomNavigationService as dL, ZoomRendererComponent as dM, ZoomTargetService as dN, addCategory as dO, addCommentToList as dP, addGradientStopPatch as dQ, addItem as dR, addSeries as dS, addSubItem as dT, advanceStep as dU, affordanceElements as dV, aiToggleVisible as dW, alignPatch as dX, animationFor as dY, animationPresetLabelKey as dZ, annotationMapToInkInserts as d_, TagsCardComponent as da, Text3DBevelSectionComponent as db, Text3DPanelComponent as dc, TextAdvancedPanelComponent as dd, ThemeEditorFieldsComponent as de, ThemeGalleryComponent as df, ThemeSelectorCardComponent as dg, TitleBarComponent as dh, TitleBarSearchComponent as di, TransitionDirectionPickerComponent as dj, TransitionPreviewComponent as dk, VALIGN_OPTIONS as dl, VIEWER_THEME as dm, VersionHistoryPanelComponent as dn, ViewerCanvasEditingService as dp, ViewerCollabCursorService as dq, ViewerCollaborationSessionService as dr, ViewerCompareService as ds, ViewerCustomShowsService as dt, ViewerDialogsService as du, ViewerDocumentPropertiesService as dv, ViewerExportService as dw, ViewerExtraDialogsComponent as dx, ViewerFileIOService as dy, ViewerFindReplaceService as dz, AVATAR_COLOR_SWATCHES as e, buildZoomContainerStyle as e$, applyAnimationPreset as e0, applyFindReplacements as e1, applyFormatToElement as e2, applyMove as e3, applyResize as e4, asMediaElement as e5, assignUserColor as e6, attachShowVisibilityPause as e7, attachTouchGestures as e8, axisTickValues as e9, buildFontFaceRule as eA, buildGradientFillCss as eB, buildGridlinesAndLabels as eC, buildHyperlinkPatch as eD, buildInkContainerStyle as eE, buildInkStrokes as eF, buildLegend as eG, buildMarkTooltip as eH, buildModel3DContainerStyle as eI, buildModel3DViewModel as eJ, buildOleActionModel as eK, buildOleInfoRows as eL, buildPatternFillCss as eM, buildPrintHtmlDocument as eN, buildPropertiesPatch as eO, buildRegionMapViewModel as eP, buildSaveSlides as eQ, buildShareUrl as eR, buildSmartArtInsertElement as eS, buildSmartArtNodes as eT, buildStockViewModel as eU, buildSurfaceViewModel as eV, buildTableViewModel as eW, buildTreemapViewModel as eX, buildTrimFragment as eY, buildWaterfallViewModel as eZ, buildZeroLine as e_, beginNodeEdit as ea, bevelSizePatch as eb, boolFromEvent as ec, bringForward as ed, bringToFront as ee, buildBarActions as ef, buildBroadcastConfig as eg, buildBroadcastViewerUrl as eh, buildCategoryLabels as ei, buildCellParagraphs as ej, buildChartViewModel as ek, buildChatLogExport as el, buildChatLogMarkdown as em, buildChromeStyle as en, buildClearHyperlinkPatch as eo, buildClickGroups as ep, buildColStyles as eq, buildCollaborationConfig as er, buildComboViewModel as es, buildCssGradientFromShapeStyle as et, buildDuotoneFilter as eu, buildDuotoneFilterId as ev, buildEmbeddedFontStyles as ew, buildEquationElement as ex, buildEquationSegment as ey, buildFallbackViewModel as ez, AXIS_LABEL_COLOR as f, computeSingleSelected as f$, buildZoomViewModel as f0, bulletIndentPx as f1, canAddTopLevelNode as f2, canGroupSelection as f3, canRemoveTopLevelNode as f4, canSetStrokeWidth as f5, canStartBroadcast as f6, canStartShare as f7, canUngroupSelection as f8, canUseClipboard as f9, computeAxisTitlePrimitives as fA, computeBarRects as fB, computeBubbleRadius as fC, computeCornerHandle as fD, computeDistribute as fE, computeDrawingViewBox as fF, computeErrorBarPrimitives as fG, computeFocusTargets as fH, computeGridSpacingPx as fI, computeHandleBoxes as fJ, computeHandoutLayout as fK, computeIsMobile as fL, computeIsTablet as fM, computeLinePoints as fN, computeLinearRegression as fO, computePageCount as fP, computePieLayout as fQ, computePieSlicePath as fR, computePieSlices as fS, computePlotLayout as fT, computeRSquared as fU, computeRadarPoints as fV, computeResizeHandleBoxes as fW, computeRotateHandleBox as fX, computeScatterDots as fY, computeScatterXDomain as fZ, computeSelectionBoxes as f_, captionDisplayText as fa, cellRunStyle as fb, cellStyleToStyleMap as fc, cellTdStyle as fd, changeCountLabel as fe, changeIcon as ff, characterSpacingPatch as fg, chartPreserveAspectRatio as fh, checkFontAvailable as fi, clampCursorPosition as fj, clampGifDimensions as fk, clampIndex as fl, clampNotesFontSize as fm, clampScale as fn, clampStep as fo, clearAllLocalViewerData as fp, clearAudienceContent as fq, cn as fr, collectAccessibilityIssues as fs, collectElementText as ft, collectSlideText as fu, collectStoredChats as fv, collectUsedFontFamilies as fw, columnWidthStyle as fx, commitNodeText as fy, computeAlign as fz, AccessibilityPanelComponent as g, formatFileSize as g$, computeSlideIndices as g0, computeSnap as g1, computeStackedBarRects as g2, computeStackedValueRange as g3, computeTrendlinePrimitives as g4, computeValueRange as g5, convertOmmlToMathMl as g6, copyFormatFromElement as g7, countAccessibilityIssues as g8, countAnnotationStrokes as g9, enableGlowPatch as gA, enableInnerShadowPatch as gB, enableOuterShadowPatch as gC, enableReflectionPatch as gD, enableSoftEdgePatch as gE, encodeGif as gF, endShowMediaCleanup as gG, estimatePageCount as gH, exitPresentationFullscreen as gI, exportAiChatLogs as gJ, extractPathPoints as gK, eyedropperAvailable as gL, fillColorOf$1 as gM, findInSlides as gN, findOwningSlideIndex as gO, findSlideIndexByElementId as gP, firstVisibleIndex as gQ, fitPolynomial as gR, fitZoom as gS, focusTargetChips as gT, fontMimeForFormat as gU, fontSizeOf as gV, forgetSessionDeck as gW, formatAxisValue as gX, formatBytes as gY, formatCursorLabel as gZ, formatElapsed as g_, createAngularAiBridge as ga, createCustomShow as gb, createSwipeDismissDrag as gc, createWebrtcBundle as gd, createWebsocketBundle as ge, cssObjectToStyleMap as gf, currentColorScheme as gg, currentLayout as gh, currentStyle as gi, defaultCssVars as gj, defaultRadius as gk, defaultThemeColors as gl, deleteElementsByIds as gm, deleteVersion as gn, demoteNode as go, deriveModel3DBlobUrl as gp, derivePresenceList as gq, describeSmartArtBounds as gr, disableGlowPatch as gs, disableInnerShadowPatch as gt, disableOuterShadowPatch as gu, disableReflectionPatch as gv, disableSoftEdgePatch as gw, duplicateElementById as gx, durationOf as gy, effectsStateOf as gz, AccessibilityService as h, isPpactionUrl as h$, formatPropertyDate as h0, formatTime as h1, fpsToFrameIntervalMs as h2, generateBroadcastRoomId as h3, generateCommentId as h4, generateCustomShowId as h5, generatePressureCircles as h6, generateTicks as h7, getClrChangeParams as h8, getContainerStyle as h9, getWarpPath as hA, gradientStateFromStyle as hB, gradientStateOf as hC, gradientStatePatch as hD, gridColumns as hE, groupIssuesBySeverity as hF, hasAnimation as hG, hasCopyableFormat as hH, hasExistingLink as hI, hasExitedFullscreen as hJ, hasGradientFill as hK, hasPressureVariation as hL, hasVisibleSlideAfter as hM, headerLabel as hN, imageDimensions as hO, inkViewBox as hP, insertTableElementColumn as hQ, insertTableElementRow as hR, interpolateWidth as hS, isAudienceTab as hT, isBold as hU, isBrowserOpenableMime as hV, isChildNode as hW, isElementInteractive as hX, isInjectableUrl as hY, isItalic as hZ, isLegacyBinaryPresentation as h_, getDuotoneFilterDef as ha, getEffectSoundState as hb, getImageSrc as hc, getLocalStorageUsageSummary as hd, getOleAriaLabel as he, getOleBadgeLabel as hf, getOleDisplayName as hg, getOleDownloadFileName as hh, getOleTypeColor as hi, getOleTypeLabel as hj, getPasswordStrength as hk, getPatternSvg as hl, getPlaceholderStyle as hm, getVersions as hn, getResolvedShapeClipPath as ho, getResolvedShapeClipPathFor as hp, getSessionTabId as hq, getShapeFillStrokeStyle as hr, getSlideBackgroundStyle as hs, getSlideTransitionAnimations as ht, getSmartArtNodeBounds as hu, getSpeechRecognitionCtor as hv, getTextBlockStyle as hw, getTextWarp as hx, getTouchDistance as hy, getWarpCategory as hz, AccountPageComponent as i, patchChartData as i$, isPresenterMessage as i0, isSigned as i1, isSupportedPresentationFile as i2, isTextElement as i3, isTwoTableFocus as i4, isUnderline as i5, isUrlSafe as i6, isValidRoomId as i7, isViewportBackgroundPressTarget as i8, isZoomActivationKey as i9, newChartElement as iA, newEquationElement as iB, newPresetShapeElement as iC, newShapeElement as iD, newSmartArtElement as iE, newTableElement as iF, newTextElement as iG, nextVisibleIndex as iH, nodeBold as iI, nodeEditBox as iJ, nodeFillColor as iK, nodeFontColor as iL, nodeIdFromKey as iM, nodeItalic as iN, nodeStyle as iO, normalizeFontFormat as iP, normalizeSlidesPerPage as iQ, normalizeValue as iR, numFromEvent as iS, ommlToMathml as iT, ooxmlDashToCssBorderStyle as iU, openNativeEyeDropper as iV, overallStatus as iW, paletteColor as iX, parseAudienceNonce as iY, parseNodeTextarea as iZ, partitionSlides as i_, issueTrackKey as ia, issueTypeLabel as ib, keyToLabel as ic, lastVisibleIndex as id, latexToMathml as ie, layoutConnectorPaints as ig, layoutNodeLabels as ih, linePointsToSvgString as ii, lineSpacingPatch as ij, loadAudienceContent as ik, loadSessionDeck as il, mediaFallbackFor as im, mediaSurfaceFor as io, mergeCaptionResults as ip, mergeDown as iq, mergeRight as ir, mergeSelection as is, moveElementBy as it, moveNodeDown as iu, moveNodeUp as iv, msToFrameDelayCs as iw, narrowToCircle as ix, narrowToPolygon as iy, narrowToRect as iz, ActionSettingsPanelComponent as j, rulerDragToGuidePosition as j$, patchChartStyle as j0, patchTableData as j1, patchTextStyle as j2, patternPresetOptions as j3, pendingElementStyles as j4, pickColorByClickFallback as j5, pickFile as j6, pickSupportedMimeType as j7, planGifFrames as j8, planVideoSegments as j9, removeSeries as jA, renderToCanvas as jB, reorderAnimationDown as jC, reorderAnimationUp as jD, replaceInSlides as jE, replaceMatch as jF, requestPresentationFullscreen as jG, resizeElement as jH, resolveCaptionTracks as jI, resolveChartKind as jJ, resolveFontVariant as jK, resolveHyperlinkHref as jL, resolveInteractiveElementId as jM, resolveMediaSrc as jN, resolveOleType as jO, resolveParagraphBullet as jP, resolvePresenterNotes as jQ, resolveProfileInitial as jR, resolveRegionCode as jS, resolveSlideAutoAdvanceMs as jT, resolvePalette as jU, resolveThemeCatalogEntry as jV, resolveTransitionDuration as jW, restoreSessionDeck as jX, revealedElementStyles as jY, routeOrthogonalConnector as jZ, rowStyle as j_, pointsToSvgPathD as ja, presenceToCursors as jb, presentationBaseName as jc, presentationStageStyle as jd, presenterTimerProgress as je, presetByLayout as jf, presetsForCategory as jg, pressuresToWidths as jh, prevVisibleIndex as ji, projectDrawingShapes as jj, promoteNode as jk, provideViewerTheme as jl, radarAngle as jm, radarRingPoints as jn, readAsDataUrl as jo, recordWebm as jp, registerCrossSlideAudio as jq, rememberSessionDeck as jr, removeAnimation as js, removeCategory as jt, removeTableElementColumn as ju, removeCommentFromList as jv, removeElementAnimation as jw, removeGradientStopPatch as jx, removeNode as jy, removeTableElementRow as jz, AdvancedChartEditorComponent as k, sheetAfterNavigate as k$, rulerHighlight as k0, rulerStripTicks as k1, sampleColorFromSlide as k2, sanitizeColor as k3, sanitizeSlideIndex as k4, sanitizeUserName as k5, saveViewerProfile as k6, savedPresentationFileName as k7, scanAvailableFonts as k8, searchSlides as k9, setDataPointMarker as kA, setDelay as kB, setDirection as kC, setDuration as kD, setEffectSound as kE, setElementPosition as kF, setGridlineStyle as kG, setLayout as kH, setLegend as kI, setNodeStyle as kJ, setNodeText as kK, setRepeatCount as kL, setRepeatMode as kM, setSequence as kN, setSeriesChartType as kO, setSeriesColor as kP, setSeriesErrorBars as kQ, setSeriesMarker as kR, setSeriesName as kS, setSeriesTrendline as kT, setSeriesValue as kU, setStyle as kV, setTimingCurve as kW, setTitle as kX, setTrigger as kY, setTriggerShapeId as kZ, shapeStylePatch$1 as k_, seedBroadcastFields as ka, seedHyperlinkDraft as kb, seedPropertiesDraft as kc, seedShareFields as kd, segmentFrameCount as ke, selectValue$2 as kf, sendBackward as kg, sendToBack as kh, sequentialColorScale as ki, serializeWriteBack as kj, seriesColor as kk, setAfterAnimation as kl, setAfterAnimationColor as km, setAnimationEmphasis as kn, setAnimationEntrance as ko, setAnimationExit as kp, setAxis as kq, setAxisLogScale as kr, setAxisTitleStyle as ks, setCategoryLabel as kt, setCellText as ku, setColorScheme as kv, setDataLabels as kw, setDataPointExplosion as kx, setDataPointFill as ky, setDataPointLabel as kz, AiChangeOverlayComponent as l, shouldBlockClickAdvance as l0, shouldUseSvgWarp as l1, showDirectionPicker as l2, showsTemplateAffordance as l3, signatureCountLabel as l4, signatureKey as l5, signatureTimestamp as l6, signerName as l7, statusLabel as l8, slideNumberOf as l9, toggleCommentResolvedInList as lA, toggleNodeBold as lB, toggleNodeItalic as lC, toggleSheet as lD, topLevelNodeCount as lE, transformSelectedTextCase as lF, translationsEn as lG, updateElementById as lH, updateGlowPatch as lI, updateGradientStopPatch as lJ, updateInnerShadowPatch as lK, updateOuterShadowPatch as lL, updateReflectionPatch as lM, vAlignPatch as lN, validatePassword as lO, validatePrintSettings as lP, validateRoomId as lQ, valueToY as lR, vermilionDarkColors as lS, vermilionDarkTheme as lT, vermilionLightColors as lU, vermilionLightTheme as lV, vermilionRadius as lW, waypointsToPathD as lX, worstStatus as lY, zoomTargetSlideIndex as lZ, slidesWithReappliedLayout as la, smartArtNodes as lb, paletteColour as lc, snapToGridStep as ld, splitCursorCell as le, splitMergedCell as lf, statusKind as lg, statusLabel$1 as lh, storeAudienceContent as li, stringFromEvent$5 as lj, strokeColorOf as lk, strokeToInkElement as ll, strokeWidthOf as lm, styleShadowFilter as ln, surfaceColor as lo, textAdvancedPatch as lp, textAdvancedStateFromStyle as lq, textAdvancedStateOf as lr, textColorOf as ls, textDirectionPatch as lt, textStyleOf as lu, textStylePatch as lv, themeStyle as lw, themeToCssVars as lx, thumbnailHeight as ly, thumbnailZoom as lz, AiChatPanelComponent as m, AiChatService as n, AiComposerComponent as o, AiFocusBarComponent as p, AiFocusHighlightOverlayComponent as q, AiHistoryMenuComponent as r, AiHistoryService as s, toChatSummary as t, AiMessageListComponent as u, AiPanelStore as v, AiProposalCardComponent as w, AiSettingsSectionComponent as x, AiToolCallCardComponent as y, AnimationAuthorPanelComponent as z };
146588
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-BaWhnpJm.mjs.map
147482
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CY6xB_ld.mjs.map