pptx-angular-viewer 3.16.7 → 3.17.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.
@@ -2,7 +2,7 @@ import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, input, output, inject, computed, ChangeDetectionStrategy, Component, signal, Injectable, DestroyRef, viewChild, effect, Injector, untracked, ElementRef, HostListener, afterNextRender, Renderer2, ViewEncapsulation, forwardRef, Directive, linkedSignal } from '@angular/core';
4
4
  import { TranslateService, TranslatePipe, translate } from '@ngx-translate/core';
5
- import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, createAutoNumberSequence, breakAutoNumberRun, nextAutoNumber, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS } from 'pptx-viewer-core';
5
+ import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, createAutoNumberSequence, nextAutoNumber, breakAutoNumberRun, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS } from 'pptx-viewer-core';
6
6
  import { parse } from 'opentype.js';
7
7
  import DOMPurify from 'dompurify';
8
8
  import { z } from 'zod';
@@ -51119,6 +51119,16 @@ const LOCALE_CATALOG = [
51119
51119
  { code: 'de', label: 'German', nativeLabel: 'Deutsch' },
51120
51120
  ];
51121
51121
 
51122
+ /** Complete action labels keep direction enums out of translated sentences. */
51123
+ const ALIGNMENT_LABEL_KEYS = {
51124
+ left: 'pptx.ribbon.alignLeft',
51125
+ center: 'pptx.ribbon.alignCenter',
51126
+ right: 'pptx.ribbon.alignRight',
51127
+ top: 'pptx.ribbon.alignTop',
51128
+ middle: 'pptx.ribbon.alignMiddle',
51129
+ bottom: 'pptx.ribbon.alignBottom',
51130
+ };
51131
+
51122
51132
  /**
51123
51133
  * slide-template-helpers.ts: element factory helpers for slide templates.
51124
51134
  *
@@ -52371,218 +52381,676 @@ function resolveParagraphIndent(paraIndent, paragraphLevel) {
52371
52381
  return { marginLeftPx: marginLeft, textIndentPx: textIndent };
52372
52382
  }
52373
52383
 
52374
- /**
52375
- * Bullet / numbered-list toggling for the ribbon's paragraph buttons.
52376
- *
52377
- * The renderer (`resolveParagraphBullet`) and the save writer
52378
- * (`applyBulletProperties`) both read a paragraph's list state from the
52379
- * `bulletInfo` of its FIRST segment; `TextStyle.listType` is consulted for
52380
- * nothing but the `'none'` suppression. Every binding's Bullets / Numbering
52381
- * button used to write `listType: 'bullet' | 'numbered'` onto the element's
52382
- * `textStyle`, a field nothing downstream reads, so the buttons were dead.
52383
- *
52384
- * These helpers author the real thing: a `BulletInfo` on each paragraph's
52385
- * first segment (`a:buChar` / `a:buAutoNum` / `a:buNone` on save), with the
52386
- * inert `listType` cleared so a stale `'none'` cannot suppress the new marker.
52387
- *
52388
- * On load core prefixes a display-only marker segment (text "• " / "1.") to a
52389
- * listed paragraph; the renderer drops it when its text matches the marker it
52390
- * would draw, and the save writer drops it because the paragraph properties
52391
- * already express it. Switching a bullet to a number (or off) would leave the
52392
- * old glyph behind as literal text, so the previous marker is removed and a
52393
- * fresh one authored in the same shape core uses.
52394
- */
52395
- /** The default character bullet PowerPoint inserts (`a:buChar char="•"`). */
52396
52384
  const DEFAULT_BULLET_CHAR = '•';
52397
- /** The default numbering scheme PowerPoint inserts (`a:buAutoNum type="arabicPeriod"`). */
52398
52385
  const DEFAULT_AUTONUM_TYPE = 'arabicPeriod';
52399
- /**
52400
- * The `BulletInfo` that authors `kind`.
52401
- *
52402
- * @param ordinal - Zero-based position of the paragraph within its numbered
52403
- * run, published as `paragraphIndex` so the renderer counts "1. 2. 3." (see
52404
- * `BulletInfo.paragraphIndex`). Ignored for the other kinds.
52405
- */
52406
52386
  function bulletInfoForKind(kind, ordinal = 0) {
52407
- switch (kind) {
52408
- case 'bullet':
52409
- return { char: DEFAULT_BULLET_CHAR };
52410
- case 'numbered':
52411
- return { autoNumType: DEFAULT_AUTONUM_TYPE, autoNumStartAt: 1, paragraphIndex: ordinal };
52412
- case 'none':
52413
- return { none: true };
52387
+ if (kind === 'none') {
52388
+ return { none: true };
52389
+ }
52390
+ if (kind === 'bullet') {
52391
+ return { char: DEFAULT_BULLET_CHAR };
52414
52392
  }
52393
+ return { autoNumType: DEFAULT_AUTONUM_TYPE, autoNumStartAt: 1, paragraphIndex: ordinal };
52415
52394
  }
52416
- /**
52417
- * Whether a segment is the display-only marker core inserts on load (mirrors
52418
- * the save writer's `isRenderedBulletMarker`): it carries `bulletInfo` and its
52419
- * text is exactly the glyph the renderer would draw for that info.
52420
- */
52395
+ /** Matches core's synthetic prefix, including picture and suppressed markers. */
52421
52396
  function isBulletMarkerSegment(segment) {
52422
- const bullet = segment.bulletInfo;
52423
- if (!bullet || bullet.none) {
52397
+ const info = segment.bulletInfo;
52398
+ if (!info || info.none || segment.fieldType || segment.isLineBreak) {
52424
52399
  return false;
52425
52400
  }
52426
- const resolved = resolveParagraphBullet(segment);
52427
- if (!resolved) {
52401
+ if (!info.char &&
52402
+ !info.autoNumType &&
52403
+ !info.imageRelId &&
52404
+ !info.imageDataUrl &&
52405
+ !info.imageBlipFillXml) {
52428
52406
  return false;
52429
52407
  }
52430
- return segment.text.trim() === resolved.marker.trim() && segment.text.trim().length > 0;
52408
+ if (info.autoNumType) {
52409
+ // Without this runtime field, a literal "1." is authored content (PR 204).
52410
+ if (info.paragraphIndex === undefined) {
52411
+ return false;
52412
+ }
52413
+ const marker = markerText(info);
52414
+ return segment.text === marker || segment.text === `${marker} `;
52415
+ }
52416
+ return segment.text === markerText(info);
52431
52417
  }
52432
- /**
52433
- * The current list state of one paragraph (its segments, separators excluded),
52434
- * derived from the resolved bullet of its first segment so an inherited
52435
- * (master / layout) bullet that core resolved on load counts as `'bullet'`.
52436
- */
52437
52418
  function paragraphBulletKind(paragraph) {
52438
52419
  const resolved = resolveParagraphBullet(paragraph[0]);
52439
- if (!resolved) {
52440
- return 'none';
52441
- }
52442
- return resolved.isNumbered ? 'numbered' : 'bullet';
52420
+ return resolved ? (resolved.isNumbered ? 'numbered' : 'bullet') : 'none';
52443
52421
  }
52444
- /** Copy of `style` without the inert `listType` flag. */
52445
52422
  function withoutListType(style) {
52446
- const next = { ...(style ?? {}) };
52423
+ const next = { ...style };
52447
52424
  delete next.listType;
52448
52425
  return next;
52449
52426
  }
52450
- function paragraphMeta(segment) {
52451
- const meta = {};
52452
- if (segment?.paragraphLevel !== undefined) {
52453
- meta.paragraphLevel = segment.paragraphLevel;
52454
- }
52455
- if (segment?.paragraphProperties !== undefined) {
52456
- meta.paragraphProperties = segment.paragraphProperties;
52427
+ function markerText(info) {
52428
+ if (info.imageRelId || info.imageDataUrl || info.imageBlipFillXml) {
52429
+ return '📎 ';
52457
52430
  }
52458
- if (segment?.endParaRunProperties !== undefined) {
52459
- meta.endParaRunProperties = segment.endParaRunProperties;
52431
+ if (info.autoNumType) {
52432
+ return formatAutoNumberMarker(info.autoNumType, Math.max(1, (info.autoNumStartAt ?? 1) + (info.paragraphIndex ?? 0)));
52460
52433
  }
52461
- return meta;
52434
+ return `${info.char ?? DEFAULT_BULLET_CHAR} `;
52462
52435
  }
52463
- /** The display text of the marker segment for a bullet / numbered `info`. */
52464
- function markerText(info) {
52465
- if (info.char) {
52466
- return `${info.char} `;
52436
+ function infoForParagraph(previous, kind, ordinal) {
52437
+ if (kind === 'none') {
52438
+ return { ...previous, none: true };
52439
+ }
52440
+ const sameKind = previous &&
52441
+ (kind === 'numbered'
52442
+ ? Boolean(previous.autoNumType)
52443
+ : Boolean(previous.char ||
52444
+ previous.imageRelId ||
52445
+ previous.imageDataUrl ||
52446
+ previous.imageBlipFillXml) && !previous.autoNumType);
52447
+ const info = sameKind ? { ...previous } : bulletInfoForKind(kind, ordinal);
52448
+ delete info.none;
52449
+ if (kind === 'numbered' && ordinal !== undefined) {
52450
+ info.paragraphIndex = ordinal;
52467
52451
  }
52468
- const ordinal = (info.autoNumStartAt ?? 1) + (info.paragraphIndex ?? 0);
52469
- return formatAutoNumberMarker(info.autoNumType ?? DEFAULT_AUTONUM_TYPE, ordinal);
52452
+ return info;
52470
52453
  }
52471
- /**
52472
- * Set one paragraph's list state to `kind`, returning the paragraph's new
52473
- * segments.
52474
- *
52475
- * The result uses the same shape core produces on load, so the renderer and
52476
- * the save writer treat an authored list exactly like a parsed one: for
52477
- * `'bullet'` / `'numbered'` a display-only marker segment carrying the new
52478
- * `bulletInfo` (and the paragraph-level fields) is placed first, followed by
52479
- * the content runs with any previous marker removed; for `'none'` the marker
52480
- * is dropped and the first content segment carries `{ none: true }`. The
52481
- * inert `style.listType` is cleared on the touched segments. An empty
52482
- * paragraph is returned unchanged since there is no run to carry the state.
52483
- *
52484
- * @param ordinal - Zero-based position within a numbered run; see
52485
- * {@link bulletInfoForKind}.
52486
- */
52487
- function toggleParagraphBullet(paragraph, kind, ordinal = 0) {
52488
- const content = paragraph.filter((segment) => !isBulletMarkerSegment(segment));
52489
- const first = content[0];
52490
- if (!first) {
52491
- return [...paragraph];
52492
- }
52493
- const meta = paragraphMeta(paragraph[0]);
52494
- const info = bulletInfoForKind(kind, ordinal);
52495
- const rest = content.slice(1);
52496
- if (kind === 'none') {
52497
- return [{ ...first, ...meta, style: withoutListType(first.style), bulletInfo: info }, ...rest];
52454
+ /** Explicit set, despite the historical name. Only the leading marker is removed. */
52455
+ function toggleParagraphBullet(paragraph, kind, ordinal) {
52456
+ const source = paragraph[0];
52457
+ if (!source) {
52458
+ return [];
52498
52459
  }
52499
- const marker = {
52500
- text: markerText(info),
52501
- style: withoutListType(first.style),
52502
- ...meta,
52503
- bulletInfo: info,
52460
+ if (paragraph.length === 1 &&
52461
+ source.paragraphInsertionStyle &&
52462
+ (source.text === '' || isBulletMarkerSegment(source))) {
52463
+ const info = infoForParagraph(source.bulletInfo, kind, ordinal);
52464
+ const picture = info.imageRelId || info.imageDataUrl || info.imageBlipFillXml;
52465
+ return [
52466
+ {
52467
+ ...source,
52468
+ text: kind === 'none' || picture ? '' : markerText(info),
52469
+ style: withoutListType(source.style),
52470
+ bulletInfo: info,
52471
+ },
52472
+ ];
52473
+ }
52474
+ const content = isBulletMarkerSegment(source) ? paragraph.slice(1) : [...paragraph];
52475
+ const first = content[0] ?? { text: '', style: source.style };
52476
+ const meta = {
52477
+ ...(source.paragraphLevel !== undefined ? { paragraphLevel: source.paragraphLevel } : {}),
52478
+ ...(source.paragraphProperties ? { paragraphProperties: source.paragraphProperties } : {}),
52479
+ ...(source.endParaRunProperties ? { endParaRunProperties: source.endParaRunProperties } : {}),
52480
+ ...(source.paragraphInsertionStyle
52481
+ ? { paragraphInsertionStyle: source.paragraphInsertionStyle }
52482
+ : {}),
52504
52483
  };
52505
- const body = { ...first, style: withoutListType(first.style) };
52484
+ const info = infoForParagraph(source.bulletInfo, kind, ordinal);
52485
+ const body = { ...first, ...meta, style: withoutListType(first.style) };
52486
+ const rest = content.slice(1).map((segment) => {
52487
+ if (!segment.bulletInfo) {
52488
+ return segment;
52489
+ }
52490
+ const run = { ...segment };
52491
+ delete run.bulletInfo;
52492
+ return run;
52493
+ });
52494
+ // Picture markers render separately; never insert their textual fallback as body.
52495
+ if (kind === 'none' || info.imageRelId || info.imageDataUrl || info.imageBlipFillXml) {
52496
+ return [{ ...body, bulletInfo: info }, ...rest];
52497
+ }
52506
52498
  delete body.bulletInfo;
52507
- return [marker, body, ...rest];
52499
+ delete body.paragraphInsertionStyle;
52500
+ const markerStyle = isBulletMarkerSegment(source) && paragraphBulletKind([source]) === kind
52501
+ ? source.style
52502
+ : first.style;
52503
+ return [
52504
+ { text: markerText(info), style: withoutListType(markerStyle), ...meta, bulletInfo: info },
52505
+ body,
52506
+ ...rest,
52507
+ ];
52508
52508
  }
52509
- function isParagraphSeparator$1(segment) {
52510
- return Boolean(segment.isParagraphBreak) || (segment.text === '\n' && !segment.isLineBreak);
52509
+ function elementSegments(element) {
52510
+ if (!hasTextProperties(element)) {
52511
+ return [];
52512
+ }
52513
+ if (element.textSegments?.length) {
52514
+ return element.textSegments;
52515
+ }
52516
+ return (element.text ?? '')
52517
+ .split('\n')
52518
+ .flatMap((text, index) => [
52519
+ ...(index ? [{ text: '\n', style: { ...element.textStyle }, isParagraphBreak: true }] : []),
52520
+ { text, style: { ...element.textStyle } },
52521
+ ]);
52511
52522
  }
52512
- /** Split a segment list into paragraphs, keeping each paragraph's terminator. */
52513
52523
  function splitParagraphs(segments) {
52514
52524
  const paragraphs = [
52515
52525
  { segments: [] },
52516
52526
  ];
52517
52527
  for (const segment of segments) {
52518
- if (isParagraphSeparator$1(segment)) {
52528
+ if (isParagraphSeparatorSegment(segment)) {
52519
52529
  paragraphs[paragraphs.length - 1].terminator = segment;
52520
52530
  paragraphs.push({ segments: [] });
52521
- continue;
52522
52531
  }
52523
- paragraphs[paragraphs.length - 1].segments.push(segment);
52532
+ else {
52533
+ paragraphs[paragraphs.length - 1].segments.push(segment);
52534
+ }
52524
52535
  }
52525
52536
  return paragraphs;
52526
52537
  }
52527
- /** The element's segments, synthesised from `text` when it carries none. */
52528
- function elementSegments(element) {
52538
+ /** Existing element-wide toggle convention: use its first nonempty paragraph. */
52539
+ function elementBulletKind(element) {
52540
+ for (const paragraph of splitParagraphs(elementSegments(element))) {
52541
+ if (paragraph.segments.length) {
52542
+ return paragraphBulletKind(paragraph.segments);
52543
+ }
52544
+ }
52545
+ return 'none';
52546
+ }
52547
+ /**
52548
+ * Explicitly set the touched paragraphs. Existing same-kind definitions survive;
52549
+ * defaults are only for new lists. Retained buNone metadata supports live off/on,
52550
+ * not restoration of a deleted definition after a save/reload.
52551
+ */
52552
+ function setElementBullets(element, kind, range) {
52529
52553
  if (!hasTextProperties(element)) {
52530
- return [];
52554
+ return {};
52531
52555
  }
52532
- if (element.textSegments && element.textSegments.length > 0) {
52533
- return element.textSegments;
52556
+ if (range &&
52557
+ (!Number.isInteger(range.startParagraph) ||
52558
+ !Number.isInteger(range.endParagraph) ||
52559
+ range.startParagraph < 0 ||
52560
+ range.endParagraph < range.startParagraph)) {
52561
+ return {};
52534
52562
  }
52535
- const style = { ...(element.textStyle ?? {}) };
52536
- const segments = [];
52537
- for (const [index, line] of (element.text ?? '').split('\n').entries()) {
52538
- if (index > 0) {
52539
- segments.push({ text: '\n', style: { ...style }, isParagraphBreak: true });
52563
+ const paragraphs = splitParagraphs(elementSegments(element));
52564
+ if (range && range.startParagraph >= paragraphs.length) {
52565
+ return {};
52566
+ }
52567
+ const next = [];
52568
+ const sequence = createAutoNumberSequence();
52569
+ for (const [index, paragraph] of paragraphs.entries()) {
52570
+ const selected = !range || (index >= range.startParagraph && index <= range.endParagraph);
52571
+ let segments = paragraph.segments;
52572
+ if (selected) {
52573
+ const empty = {
52574
+ ...paragraph.terminator,
52575
+ text: '',
52576
+ style: { ...paragraph.terminator?.style },
52577
+ };
52578
+ delete empty.isParagraphBreak;
52579
+ delete empty.isLineBreak;
52580
+ segments = toggleParagraphBullet(segments.length ? segments : [empty], kind);
52581
+ }
52582
+ const first = segments[0] ?? paragraph.terminator;
52583
+ const info = first?.bulletInfo;
52584
+ const level = first?.paragraphLevel ?? 0;
52585
+ if (info?.autoNumType && paragraphBulletKind(segments) === 'numbered') {
52586
+ const startAt = info.autoNumStartAt ?? 1;
52587
+ const ordinal = nextAutoNumber(sequence, level, info.autoNumType, startAt) - startAt;
52588
+ // List membership changes also renumber following items. Only this
52589
+ // derived ordinal changes outside the selected paragraphs.
52590
+ if (info.paragraphIndex !== ordinal) {
52591
+ segments = toggleParagraphBullet(segments, 'numbered', ordinal);
52592
+ }
52593
+ }
52594
+ else {
52595
+ breakAutoNumberRun(sequence, level);
52596
+ }
52597
+ next.push(...segments);
52598
+ if (paragraph.terminator) {
52599
+ next.push(paragraph.terminator);
52540
52600
  }
52541
- segments.push({ text: line, style: { ...style } });
52542
52601
  }
52543
- return segments;
52602
+ return {
52603
+ textSegments: next,
52604
+ textStyle: withoutListType(element.textStyle),
52605
+ };
52606
+ }
52607
+ /** Button intent, unlike the explicit style setter above. */
52608
+ function toggleElementBullets(element, kind) {
52609
+ return setElementBullets(element, elementBulletKind(element) === kind ? 'none' : kind);
52544
52610
  }
52611
+
52612
+ /** Keep a runless paragraph's future body formatting in the same style edit. */
52613
+ function updateTextSegmentStyle(segment, updates, options = {}) {
52614
+ return {
52615
+ ...segment,
52616
+ ...(options.updateBodyStyle === false ? {} : { style: { ...segment.style, ...updates } }),
52617
+ ...(segment.paragraphInsertionStyle
52618
+ ? { paragraphInsertionStyle: { ...segment.paragraphInsertionStyle, ...updates } }
52619
+ : {}),
52620
+ };
52621
+ }
52622
+
52545
52623
  /**
52546
- * The list state an element's ribbon buttons should show: the kind of its
52547
- * first non-empty paragraph, since that is what a toggle would act on.
52624
+ * Read the current browser selection and, if it falls within an
52625
+ * `[data-inline-editor]` element, return the segment-level range.
52626
+ *
52627
+ * Returns `null` when there is no editable text selected, the selection is
52628
+ * collapsed (just a cursor), or the selection is outside the inline editor.
52548
52629
  */
52549
- function elementBulletKind(element) {
52550
- for (const paragraph of splitParagraphs(elementSegments(element))) {
52551
- if (paragraph.segments.length > 0) {
52552
- return paragraphBulletKind(paragraph.segments);
52630
+ function getInlineEditorSelection(segments) {
52631
+ if (!segments?.length) {
52632
+ return null;
52633
+ }
52634
+ const selection = window.getSelection();
52635
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
52636
+ return null;
52637
+ }
52638
+ // A Range is always in document order, including for a backwards selection.
52639
+ const range = selection.getRangeAt(0);
52640
+ const editor = findEditorContainer(range.startContainer);
52641
+ if (!editor || !editor.contains(range.endContainer) || range.toString().length === 0) {
52642
+ return null;
52643
+ }
52644
+ const start = getSegmentPosition(editor, range.startContainer, range.startOffset, segments);
52645
+ const end = getSegmentPosition(editor, range.endContainer, range.endOffset, segments);
52646
+ if (!start || !end) {
52647
+ return null;
52648
+ }
52649
+ const renderedSpans = Array.from(editor.querySelectorAll('[data-seg-idx]'));
52650
+ const startSpanIndex = renderedSpans.indexOf(start.span);
52651
+ const endSpanIndex = renderedSpans.indexOf(end.span);
52652
+ if (startSpanIndex < 0 || endSpanIndex < startSpanIndex) {
52653
+ return null;
52654
+ }
52655
+ const selectedSpans = renderedSpans.slice(startSpanIndex, endSpanIndex + 1);
52656
+ const first = selectedSpans.find((span) => isEditableSpan(span, segments) && (span !== start.span || start.offset < start.textLength));
52657
+ const last = [...selectedSpans]
52658
+ .reverse()
52659
+ .find((span) => isEditableSpan(span, segments) && (span !== end.span || end.offset > 0));
52660
+ if (!first || !last) {
52661
+ return null;
52662
+ }
52663
+ return {
52664
+ startSegIdx: getSegmentIndex(first),
52665
+ startOffset: first === start.span ? start.offset : 0,
52666
+ endSegIdx: getSegmentIndex(last),
52667
+ endOffset: last === end.span ? end.offset : (last.textContent?.length ?? 0),
52668
+ };
52669
+ }
52670
+ function isEditableSpan(span, segments) {
52671
+ const segment = segments[getSegmentIndex(span)];
52672
+ return Boolean(segment &&
52673
+ !segment.isParagraphBreak &&
52674
+ segment.text !== '\n' &&
52675
+ !isBulletMarkerSegment(segment) &&
52676
+ (span.textContent?.length ?? 0) > 0);
52677
+ }
52678
+ function getSegmentIndex(span) {
52679
+ return Number(span.getAttribute('data-seg-idx'));
52680
+ }
52681
+ function findEditorContainer(node) {
52682
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
52683
+ return element?.closest('[data-inline-editor]') ?? null;
52684
+ }
52685
+ function getSegmentPosition(editor, node, offset, segments) {
52686
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
52687
+ const span = element?.closest('[data-seg-idx]');
52688
+ if (!span || !editor.contains(span)) {
52689
+ return null;
52690
+ }
52691
+ const segIdx = getSegmentIndex(span);
52692
+ if (!Number.isInteger(segIdx) || segIdx < 0 || segIdx >= segments.length) {
52693
+ return null;
52694
+ }
52695
+ return {
52696
+ segIdx,
52697
+ offset: getTextOffsetWithin(span, node, offset),
52698
+ span,
52699
+ textLength: span.textContent?.length ?? 0,
52700
+ };
52701
+ }
52702
+ function getTextOffsetWithin(container, targetNode, targetOffset) {
52703
+ if (targetNode === container || targetNode.nodeType === Node.ELEMENT_NODE) {
52704
+ const parent = targetNode === container ? container : targetNode;
52705
+ let count = 0;
52706
+ for (let index = 0; index < targetOffset && index < parent.childNodes.length; index++) {
52707
+ count += parent.childNodes[index].textContent?.length ?? 0;
52553
52708
  }
52709
+ return count;
52554
52710
  }
52555
- return 'none';
52711
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
52712
+ let charCount = 0;
52713
+ let node;
52714
+ while ((node = walker.nextNode())) {
52715
+ if (node === targetNode) {
52716
+ return charCount + targetOffset;
52717
+ }
52718
+ charCount += node.length;
52719
+ }
52720
+ return charCount;
52721
+ }
52722
+
52723
+ let pendingRestore = null;
52724
+ function setPendingSelectionRestore(sel) {
52725
+ pendingRestore = sel;
52726
+ }
52727
+ /** Read-once: clears the stored value after returning it. */
52728
+ function getPendingSelectionRestore() {
52729
+ const sel = pendingRestore;
52730
+ pendingRestore = null;
52731
+ return sel;
52556
52732
  }
52557
52733
  /**
52558
- * Set every paragraph of an element to `kind`, returning the element patch
52559
- * (`textSegments` rewritten; `textStyle.listType` cleared so the element-level
52560
- * flag can no longer suppress or lie about the state). Numbered paragraphs are
52561
- * counted consecutively so the renderer shows "1. 2. 3.".
52734
+ * Apply `updates` only to the characters within the selection range. Segments
52735
+ * at the boundaries are split; segments outside the range are copied unchanged.
52736
+ * Paragraph-break segments (`\n`) are always passed through unchanged.
52737
+ *
52738
+ * Returns the new segments array AND the selection coordinates mapped to the
52739
+ * new segment indices (for cursor restoration).
52562
52740
  */
52563
- function setElementBullets(element, kind) {
52564
- const textStyle = withoutListType(hasTextProperties(element) ? element.textStyle : undefined);
52565
- const next = [];
52566
- let ordinal = 0;
52567
- for (const paragraph of splitParagraphs(elementSegments(element))) {
52568
- if (paragraph.segments.length > 0) {
52569
- next.push(...toggleParagraphBullet(paragraph.segments, kind, ordinal));
52570
- ordinal += 1;
52741
+ function applyStyleToSelectedSegments(segments, selection, updates) {
52742
+ const { startSegIdx, startOffset, endSegIdx, endOffset } = selection;
52743
+ const result = [];
52744
+ // Track new indices for the start/end of the selected text in the new array.
52745
+ let newStartSegIdx = -1;
52746
+ let newStartOffset = 0;
52747
+ let newEndSegIdx = -1;
52748
+ let newEndOffset = 0;
52749
+ for (let i = 0; i < segments.length; i++) {
52750
+ const seg = i >= startSegIdx && i <= endSegIdx
52751
+ ? updateTextSegmentStyle(segments[i], updates, { updateBodyStyle: false })
52752
+ : segments[i];
52753
+ // Paragraph-break segments always pass through.
52754
+ if (seg.isParagraphBreak || seg.text === '\n') {
52755
+ result.push({ ...seg, style: { ...seg.style } });
52756
+ continue;
52571
52757
  }
52572
- if (paragraph.terminator) {
52573
- next.push(paragraph.terminator);
52758
+ // Before selection range.
52759
+ if (i < startSegIdx) {
52760
+ result.push({ ...seg, style: { ...seg.style } });
52761
+ continue;
52762
+ }
52763
+ // After selection range.
52764
+ if (i > endSegIdx) {
52765
+ result.push({ ...seg, style: { ...seg.style } });
52766
+ continue;
52767
+ }
52768
+ // Single-segment selection (start and end in the same segment).
52769
+ if (seg.paragraphInsertionStyle && (seg.text === '' || isBulletMarkerSegment(seg))) {
52770
+ newStartSegIdx = newStartSegIdx < 0 ? result.length : newStartSegIdx;
52771
+ newEndSegIdx = result.length;
52772
+ result.push(seg);
52773
+ continue;
52774
+ }
52775
+ if (i === startSegIdx && i === endSegIdx) {
52776
+ splitSingle(seg, startOffset, endOffset, updates, result);
52777
+ // Track the new selection: the selected part is at `result.length - 1`
52778
+ // (or `result.length - 2` if there's an after part).
52779
+ const partsAdded = (startOffset > 0 ? 1 : 0) + 1 + (endOffset < seg.text.length ? 1 : 0);
52780
+ const selectedPartIdx = result.length - partsAdded + (startOffset > 0 ? 1 : 0);
52781
+ newStartSegIdx = selectedPartIdx;
52782
+ newStartOffset = 0;
52783
+ newEndSegIdx = selectedPartIdx;
52784
+ newEndOffset = endOffset - startOffset;
52785
+ continue;
52786
+ }
52787
+ // Start segment of multi-segment selection.
52788
+ if (i === startSegIdx) {
52789
+ if (startOffset === 0) {
52790
+ newStartSegIdx = result.length;
52791
+ newStartOffset = 0;
52792
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52793
+ }
52794
+ else {
52795
+ // Before-selection part.
52796
+ const beforeSeg = {
52797
+ text: seg.text.slice(0, startOffset),
52798
+ style: { ...seg.style },
52799
+ };
52800
+ if (seg.bulletInfo) {
52801
+ beforeSeg.bulletInfo = seg.bulletInfo;
52802
+ }
52803
+ result.push(beforeSeg);
52804
+ // Selected part.
52805
+ newStartSegIdx = result.length;
52806
+ newStartOffset = 0;
52807
+ result.push({
52808
+ text: seg.text.slice(startOffset),
52809
+ style: { ...seg.style, ...updates },
52810
+ });
52811
+ }
52812
+ continue;
52813
+ }
52814
+ // End segment of multi-segment selection.
52815
+ if (i === endSegIdx) {
52816
+ if (endOffset >= seg.text.length) {
52817
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52818
+ newEndSegIdx = result.length - 1;
52819
+ newEndOffset = seg.text.length;
52820
+ }
52821
+ else {
52822
+ // Selected part.
52823
+ result.push({
52824
+ text: seg.text.slice(0, endOffset),
52825
+ style: { ...seg.style, ...updates },
52826
+ });
52827
+ newEndSegIdx = result.length - 1;
52828
+ newEndOffset = endOffset;
52829
+ // After-selection part.
52830
+ result.push({
52831
+ text: seg.text.slice(endOffset),
52832
+ style: { ...seg.style },
52833
+ });
52834
+ }
52835
+ continue;
52836
+ }
52837
+ // Middle segment: entirely within selection.
52838
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52839
+ }
52840
+ return {
52841
+ newSegments: result,
52842
+ newSelection: {
52843
+ startSegIdx: newStartSegIdx,
52844
+ startOffset: newStartOffset,
52845
+ endSegIdx: newEndSegIdx,
52846
+ endOffset: newEndOffset,
52847
+ },
52848
+ };
52849
+ }
52850
+ function splitSingle(seg, startOffset, endOffset, updates, result) {
52851
+ // Entire segment selected.
52852
+ if (startOffset === 0 && endOffset >= seg.text.length) {
52853
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52854
+ return;
52855
+ }
52856
+ // Before-selection part.
52857
+ if (startOffset > 0) {
52858
+ const beforeSeg = {
52859
+ text: seg.text.slice(0, startOffset),
52860
+ style: { ...seg.style },
52861
+ };
52862
+ if (seg.bulletInfo) {
52863
+ beforeSeg.bulletInfo = seg.bulletInfo;
52574
52864
  }
52865
+ result.push(beforeSeg);
52866
+ }
52867
+ // Selected part.
52868
+ result.push({
52869
+ text: seg.text.slice(startOffset, endOffset),
52870
+ style: { ...seg.style, ...updates },
52871
+ });
52872
+ // After-selection part.
52873
+ if (endOffset < seg.text.length) {
52874
+ result.push({
52875
+ text: seg.text.slice(endOffset),
52876
+ style: { ...seg.style },
52877
+ });
52575
52878
  }
52576
- return { textSegments: next, textStyle };
52577
52879
  }
52578
52880
  /**
52579
- * The ribbon button behaviour: pressing Bullets (or Numbering) on an element
52580
- * already in that state turns its lists off, otherwise it applies that kind
52581
- * to every paragraph. Returns the element patch to apply through the
52582
- * binding's update-element operation.
52881
+ * Set the DOM selection inside the inline editor using segment-level
52882
+ * coordinates. Finds `[data-seg-idx]` spans and navigates to the correct
52883
+ * text-node offsets.
52583
52884
  */
52584
- function toggleElementBullets(element, kind) {
52585
- return setElementBullets(element, elementBulletKind(element) === kind ? 'none' : kind);
52885
+ function restoreSegmentSelection(editor, startSegIdx, startOffset, endSegIdx, endOffset) {
52886
+ const sel = window.getSelection();
52887
+ if (!sel) {
52888
+ return;
52889
+ }
52890
+ const startPos = findTextPositionInSegment(editor, startSegIdx, startOffset);
52891
+ const endPos = findTextPositionInSegment(editor, endSegIdx, endOffset);
52892
+ if (!startPos || !endPos) {
52893
+ return;
52894
+ }
52895
+ const range = document.createRange();
52896
+ range.setStart(startPos.node, startPos.offset);
52897
+ range.setEnd(endPos.node, endPos.offset);
52898
+ sel.removeAllRanges();
52899
+ sel.addRange(range);
52900
+ }
52901
+ function findTextPositionInSegment(editor, segIdx, charOffset) {
52902
+ const segSpan = editor.querySelector(`[data-seg-idx="${segIdx}"]`);
52903
+ if (!segSpan) {
52904
+ return null;
52905
+ }
52906
+ const walker = document.createTreeWalker(segSpan, NodeFilter.SHOW_TEXT);
52907
+ let charCount = 0;
52908
+ let node;
52909
+ while ((node = walker.nextNode())) {
52910
+ const textLen = node.length;
52911
+ if (charCount + textLen >= charOffset) {
52912
+ return { node, offset: charOffset - charCount };
52913
+ }
52914
+ charCount += textLen;
52915
+ }
52916
+ // If exact position not found, place at end of last text node.
52917
+ const lastTextNode = segSpan.querySelector('*') ? null : segSpan.firstChild;
52918
+ if (lastTextNode && lastTextNode.nodeType === Node.TEXT_NODE) {
52919
+ return { node: lastTextNode, offset: lastTextNode.length };
52920
+ }
52921
+ return null;
52922
+ }
52923
+
52924
+ /** Body offsets ignore only the leading display marker of each paragraph. */
52925
+ function positions(segments) {
52926
+ let offset = 0;
52927
+ let paragraph = 0;
52928
+ let first = true;
52929
+ return segments.map((segment) => {
52930
+ const marker = first && isBulletMarkerSegment(segment);
52931
+ const start = offset;
52932
+ if (!marker) {
52933
+ offset += segment.text.length;
52934
+ }
52935
+ const entry = {
52936
+ start,
52937
+ end: offset,
52938
+ paragraph,
52939
+ editable: !marker && !isParagraphSeparatorSegment(segment),
52940
+ };
52941
+ first = isParagraphSeparatorSegment(segment);
52942
+ if (first) {
52943
+ paragraph += 1;
52944
+ }
52945
+ return entry;
52946
+ });
52947
+ }
52948
+ function restorePoint(segments, offset, end) {
52949
+ const entries = positions(segments);
52950
+ let fallback = { index: 0, offset: 0 };
52951
+ for (const [index, entry] of entries.entries()) {
52952
+ if (!entry.editable) {
52953
+ continue;
52954
+ }
52955
+ fallback = { index, offset: segments[index].text.length };
52956
+ if (end ? offset <= entry.end : offset < entry.end) {
52957
+ return { index, offset: Math.max(0, offset - entry.start) };
52958
+ }
52959
+ }
52960
+ return fallback;
52961
+ }
52962
+ /** Keep paragraph metadata on the first run when character styling splits it. */
52963
+ function restoreParagraphMetadata$1(original, updated) {
52964
+ const firstRuns = original.filter((_, index) => index === 0 || isParagraphSeparatorSegment(original[index - 1]));
52965
+ let paragraph = 0;
52966
+ return updated.map((segment, index) => {
52967
+ const first = index === 0 || isParagraphSeparatorSegment(updated[index - 1]);
52968
+ if (!first) {
52969
+ return segment;
52970
+ }
52971
+ const source = firstRuns[paragraph++];
52972
+ if (!source) {
52973
+ return segment;
52974
+ }
52975
+ return {
52976
+ ...segment,
52977
+ bulletInfo: source.bulletInfo,
52978
+ paragraphLevel: source.paragraphLevel,
52979
+ paragraphProperties: source.paragraphProperties,
52980
+ endParaRunProperties: source.endParaRunProperties,
52981
+ };
52982
+ });
52983
+ }
52984
+ /** Current kind at the first selected paragraph; otherwise the element default. */
52985
+ function selectedParagraphBulletKind(element, selection) {
52986
+ if (!selection || !hasTextProperties(element) || !element.textSegments) {
52987
+ return elementBulletKind(element);
52988
+ }
52989
+ let first = selection.startSegIdx;
52990
+ while (first > 0 && !isParagraphSeparatorSegment(element.textSegments[first - 1])) {
52991
+ first -= 1;
52992
+ }
52993
+ return paragraphBulletKind(element.textSegments.slice(first));
52994
+ }
52995
+ /**
52996
+ * Apply a list request to touched paragraphs, while accompanying character
52997
+ * styles retain their existing selection scope. A null selection means the
52998
+ * whole element, matching the existing editor contract.
52999
+ */
53000
+ function applyListStyleUpdate(element, updates, selection) {
53001
+ if (!hasTextProperties(element) || !updates.listType) {
53002
+ return { patch: {}, selection };
53003
+ }
53004
+ const { listType, ...characterStyle } = updates;
53005
+ let segments = element.textSegments;
53006
+ let workingSelection = selection;
53007
+ if (segments && Object.keys(characterStyle).length > 0) {
53008
+ if (selection) {
53009
+ const styled = applyStyleToSelectedSegments(segments, selection, characterStyle);
53010
+ segments = restoreParagraphMetadata$1(segments, styled.newSegments);
53011
+ workingSelection = styled.newSelection;
53012
+ }
53013
+ else {
53014
+ segments = segments.map((segment) => updateTextSegmentStyle(segment, characterStyle));
53015
+ }
53016
+ }
53017
+ const working = {
53018
+ ...element,
53019
+ textSegments: segments,
53020
+ textStyle: selection ? element.textStyle : { ...element.textStyle, ...characterStyle },
53021
+ };
53022
+ if (!workingSelection || !segments) {
53023
+ return { patch: setElementBullets(working, listType), selection: null };
53024
+ }
53025
+ const entries = positions(segments);
53026
+ const startEntry = entries[workingSelection.startSegIdx];
53027
+ const endEntry = entries[workingSelection.endSegIdx];
53028
+ if (!startEntry || !endEntry) {
53029
+ return { patch: {}, selection: null };
53030
+ }
53031
+ const startOffset = startEntry.start + workingSelection.startOffset;
53032
+ const endOffset = endEntry.start + workingSelection.endOffset;
53033
+ const lastSelected = [...entries].reverse().find((entry) => entry.start < endOffset);
53034
+ const patch = setElementBullets(working, listType, {
53035
+ startParagraph: startEntry.paragraph,
53036
+ endParagraph: lastSelected?.paragraph ?? endEntry.paragraph,
53037
+ });
53038
+ const next = { ...working, ...patch };
53039
+ const nextSegments = hasTextProperties(next) ? next.textSegments : undefined;
53040
+ if (!nextSegments) {
53041
+ return { patch, selection: null };
53042
+ }
53043
+ const start = restorePoint(nextSegments, startOffset, false);
53044
+ const end = restorePoint(nextSegments, endOffset, true);
53045
+ return {
53046
+ patch,
53047
+ selection: {
53048
+ startSegIdx: start.index,
53049
+ startOffset: start.offset,
53050
+ endSegIdx: end.index,
53051
+ endOffset: end.offset,
53052
+ },
53053
+ };
52586
53054
  }
52587
53055
 
52588
53056
  /**
@@ -61984,299 +62452,6 @@ function buildLeaderString(leader, widthPx, fontSizePx = 16) {
61984
62452
  return char.repeat(count);
61985
62453
  }
61986
62454
 
61987
- /**
61988
- * Read the current browser selection and, if it falls within an
61989
- * `[data-inline-editor]` element, return the segment-level range.
61990
- *
61991
- * Returns `null` when there is no editable text selected, the selection is
61992
- * collapsed (just a cursor), or the selection is outside the inline editor.
61993
- */
61994
- function getInlineEditorSelection(segments) {
61995
- if (!segments?.length) {
61996
- return null;
61997
- }
61998
- const selection = window.getSelection();
61999
- if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
62000
- return null;
62001
- }
62002
- // A Range is always in document order, including for a backwards selection.
62003
- const range = selection.getRangeAt(0);
62004
- const editor = findEditorContainer(range.startContainer);
62005
- if (!editor || !editor.contains(range.endContainer) || range.toString().length === 0) {
62006
- return null;
62007
- }
62008
- const start = getSegmentPosition(editor, range.startContainer, range.startOffset, segments);
62009
- const end = getSegmentPosition(editor, range.endContainer, range.endOffset, segments);
62010
- if (!start || !end) {
62011
- return null;
62012
- }
62013
- const renderedSpans = Array.from(editor.querySelectorAll('[data-seg-idx]'));
62014
- const startSpanIndex = renderedSpans.indexOf(start.span);
62015
- const endSpanIndex = renderedSpans.indexOf(end.span);
62016
- if (startSpanIndex < 0 || endSpanIndex < startSpanIndex) {
62017
- return null;
62018
- }
62019
- const selectedSpans = renderedSpans.slice(startSpanIndex, endSpanIndex + 1);
62020
- const first = selectedSpans.find((span) => isEditableSpan(span, segments) && (span !== start.span || start.offset < start.textLength));
62021
- const last = [...selectedSpans]
62022
- .reverse()
62023
- .find((span) => isEditableSpan(span, segments) && (span !== end.span || end.offset > 0));
62024
- if (!first || !last) {
62025
- return null;
62026
- }
62027
- return {
62028
- startSegIdx: getSegmentIndex(first),
62029
- startOffset: first === start.span ? start.offset : 0,
62030
- endSegIdx: getSegmentIndex(last),
62031
- endOffset: last === end.span ? end.offset : (last.textContent?.length ?? 0),
62032
- };
62033
- }
62034
- function isEditableSpan(span, segments) {
62035
- const segment = segments[getSegmentIndex(span)];
62036
- return Boolean(segment &&
62037
- !segment.isParagraphBreak &&
62038
- segment.text !== '\n' &&
62039
- !isBulletMarkerSegment(segment) &&
62040
- (span.textContent?.length ?? 0) > 0);
62041
- }
62042
- function getSegmentIndex(span) {
62043
- return Number(span.getAttribute('data-seg-idx'));
62044
- }
62045
- function findEditorContainer(node) {
62046
- const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
62047
- return element?.closest('[data-inline-editor]') ?? null;
62048
- }
62049
- function getSegmentPosition(editor, node, offset, segments) {
62050
- const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
62051
- const span = element?.closest('[data-seg-idx]');
62052
- if (!span || !editor.contains(span)) {
62053
- return null;
62054
- }
62055
- const segIdx = getSegmentIndex(span);
62056
- if (!Number.isInteger(segIdx) || segIdx < 0 || segIdx >= segments.length) {
62057
- return null;
62058
- }
62059
- return {
62060
- segIdx,
62061
- offset: getTextOffsetWithin(span, node, offset),
62062
- span,
62063
- textLength: span.textContent?.length ?? 0,
62064
- };
62065
- }
62066
- function getTextOffsetWithin(container, targetNode, targetOffset) {
62067
- if (targetNode === container || targetNode.nodeType === Node.ELEMENT_NODE) {
62068
- const parent = targetNode === container ? container : targetNode;
62069
- let count = 0;
62070
- for (let index = 0; index < targetOffset && index < parent.childNodes.length; index++) {
62071
- count += parent.childNodes[index].textContent?.length ?? 0;
62072
- }
62073
- return count;
62074
- }
62075
- const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
62076
- let charCount = 0;
62077
- let node;
62078
- while ((node = walker.nextNode())) {
62079
- if (node === targetNode) {
62080
- return charCount + targetOffset;
62081
- }
62082
- charCount += node.length;
62083
- }
62084
- return charCount;
62085
- }
62086
-
62087
- let pendingRestore = null;
62088
- function setPendingSelectionRestore(sel) {
62089
- pendingRestore = sel;
62090
- }
62091
- /** Read-once: clears the stored value after returning it. */
62092
- function getPendingSelectionRestore() {
62093
- const sel = pendingRestore;
62094
- pendingRestore = null;
62095
- return sel;
62096
- }
62097
- /**
62098
- * Apply `updates` only to the characters within the selection range. Segments
62099
- * at the boundaries are split; segments outside the range are copied unchanged.
62100
- * Paragraph-break segments (`\n`) are always passed through unchanged.
62101
- *
62102
- * Returns the new segments array AND the selection coordinates mapped to the
62103
- * new segment indices (for cursor restoration).
62104
- */
62105
- function applyStyleToSelectedSegments(segments, selection, updates) {
62106
- const { startSegIdx, startOffset, endSegIdx, endOffset } = selection;
62107
- const result = [];
62108
- // Track new indices for the start/end of the selected text in the new array.
62109
- let newStartSegIdx = -1;
62110
- let newStartOffset = 0;
62111
- let newEndSegIdx = -1;
62112
- let newEndOffset = 0;
62113
- for (let i = 0; i < segments.length; i++) {
62114
- const seg = segments[i];
62115
- // Paragraph-break segments always pass through.
62116
- if (seg.isParagraphBreak || seg.text === '\n') {
62117
- result.push({ ...seg, style: { ...seg.style } });
62118
- continue;
62119
- }
62120
- // Before selection range.
62121
- if (i < startSegIdx) {
62122
- result.push({ ...seg, style: { ...seg.style } });
62123
- continue;
62124
- }
62125
- // After selection range.
62126
- if (i > endSegIdx) {
62127
- result.push({ ...seg, style: { ...seg.style } });
62128
- continue;
62129
- }
62130
- // Single-segment selection (start and end in the same segment).
62131
- if (i === startSegIdx && i === endSegIdx) {
62132
- splitSingle(seg, startOffset, endOffset, updates, result);
62133
- // Track the new selection: the selected part is at `result.length - 1`
62134
- // (or `result.length - 2` if there's an after part).
62135
- const partsAdded = (startOffset > 0 ? 1 : 0) + 1 + (endOffset < seg.text.length ? 1 : 0);
62136
- const selectedPartIdx = result.length - partsAdded + (startOffset > 0 ? 1 : 0);
62137
- newStartSegIdx = selectedPartIdx;
62138
- newStartOffset = 0;
62139
- newEndSegIdx = selectedPartIdx;
62140
- newEndOffset = endOffset - startOffset;
62141
- continue;
62142
- }
62143
- // Start segment of multi-segment selection.
62144
- if (i === startSegIdx) {
62145
- if (startOffset === 0) {
62146
- newStartSegIdx = result.length;
62147
- newStartOffset = 0;
62148
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62149
- }
62150
- else {
62151
- // Before-selection part.
62152
- const beforeSeg = {
62153
- text: seg.text.slice(0, startOffset),
62154
- style: { ...seg.style },
62155
- };
62156
- if (seg.bulletInfo) {
62157
- beforeSeg.bulletInfo = seg.bulletInfo;
62158
- }
62159
- result.push(beforeSeg);
62160
- // Selected part.
62161
- newStartSegIdx = result.length;
62162
- newStartOffset = 0;
62163
- result.push({
62164
- text: seg.text.slice(startOffset),
62165
- style: { ...seg.style, ...updates },
62166
- });
62167
- }
62168
- continue;
62169
- }
62170
- // End segment of multi-segment selection.
62171
- if (i === endSegIdx) {
62172
- if (endOffset >= seg.text.length) {
62173
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62174
- newEndSegIdx = result.length - 1;
62175
- newEndOffset = seg.text.length;
62176
- }
62177
- else {
62178
- // Selected part.
62179
- result.push({
62180
- text: seg.text.slice(0, endOffset),
62181
- style: { ...seg.style, ...updates },
62182
- });
62183
- newEndSegIdx = result.length - 1;
62184
- newEndOffset = endOffset;
62185
- // After-selection part.
62186
- result.push({
62187
- text: seg.text.slice(endOffset),
62188
- style: { ...seg.style },
62189
- });
62190
- }
62191
- continue;
62192
- }
62193
- // Middle segment: entirely within selection.
62194
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62195
- }
62196
- return {
62197
- newSegments: result,
62198
- newSelection: {
62199
- startSegIdx: newStartSegIdx,
62200
- startOffset: newStartOffset,
62201
- endSegIdx: newEndSegIdx,
62202
- endOffset: newEndOffset,
62203
- },
62204
- };
62205
- }
62206
- function splitSingle(seg, startOffset, endOffset, updates, result) {
62207
- // Entire segment selected.
62208
- if (startOffset === 0 && endOffset >= seg.text.length) {
62209
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62210
- return;
62211
- }
62212
- // Before-selection part.
62213
- if (startOffset > 0) {
62214
- const beforeSeg = {
62215
- text: seg.text.slice(0, startOffset),
62216
- style: { ...seg.style },
62217
- };
62218
- if (seg.bulletInfo) {
62219
- beforeSeg.bulletInfo = seg.bulletInfo;
62220
- }
62221
- result.push(beforeSeg);
62222
- }
62223
- // Selected part.
62224
- result.push({
62225
- text: seg.text.slice(startOffset, endOffset),
62226
- style: { ...seg.style, ...updates },
62227
- });
62228
- // After-selection part.
62229
- if (endOffset < seg.text.length) {
62230
- result.push({
62231
- text: seg.text.slice(endOffset),
62232
- style: { ...seg.style },
62233
- });
62234
- }
62235
- }
62236
- /**
62237
- * Set the DOM selection inside the inline editor using segment-level
62238
- * coordinates. Finds `[data-seg-idx]` spans and navigates to the correct
62239
- * text-node offsets.
62240
- */
62241
- function restoreSegmentSelection(editor, startSegIdx, startOffset, endSegIdx, endOffset) {
62242
- const sel = window.getSelection();
62243
- if (!sel) {
62244
- return;
62245
- }
62246
- const startPos = findTextPositionInSegment(editor, startSegIdx, startOffset);
62247
- const endPos = findTextPositionInSegment(editor, endSegIdx, endOffset);
62248
- if (!startPos || !endPos) {
62249
- return;
62250
- }
62251
- const range = document.createRange();
62252
- range.setStart(startPos.node, startPos.offset);
62253
- range.setEnd(endPos.node, endPos.offset);
62254
- sel.removeAllRanges();
62255
- sel.addRange(range);
62256
- }
62257
- function findTextPositionInSegment(editor, segIdx, charOffset) {
62258
- const segSpan = editor.querySelector(`[data-seg-idx="${segIdx}"]`);
62259
- if (!segSpan) {
62260
- return null;
62261
- }
62262
- const walker = document.createTreeWalker(segSpan, NodeFilter.SHOW_TEXT);
62263
- let charCount = 0;
62264
- let node;
62265
- while ((node = walker.nextNode())) {
62266
- const textLen = node.length;
62267
- if (charCount + textLen >= charOffset) {
62268
- return { node, offset: charOffset - charCount };
62269
- }
62270
- charCount += textLen;
62271
- }
62272
- // If exact position not found, place at end of last text node.
62273
- const lastTextNode = segSpan.querySelector('*') ? null : segSpan.firstChild;
62274
- if (lastTextNode && lastTextNode.nodeType === Node.TEXT_NODE) {
62275
- return { node: lastTextNode, offset: lastTextNode.length };
62276
- }
62277
- return null;
62278
- }
62279
-
62280
62455
  /**
62281
62456
  * Caret placement for the inline text editors.
62282
62457
  *
@@ -63987,6 +64162,231 @@ function connectorArrowPatch(control, raw) {
63987
64162
  return { [control.styleKey]: raw };
63988
64163
  }
63989
64164
 
64165
+ /**
64166
+ * Regular-text font sizes are stored in slide/CSS pixels in the shared model,
64167
+ * while PowerPoint's font controls and the preset list below use points.
64168
+ */
64169
+ function textFontSizePxToPt(fontSizePx) {
64170
+ // DrawingML stores regular text sizes in hundredths of a point. Normalising
64171
+ // to that precision removes binary floating-point noise without discarding
64172
+ // valid authored values such as 10.5 pt or 48.1 pt.
64173
+ return Math.round(fontSizePx * (72 / 96) * 100) / 100;
64174
+ }
64175
+ /** Convert a PowerPoint font-control value in points to the model's pixels. */
64176
+ function textFontSizePtToPx(fontSizePt) {
64177
+ return fontSizePt * (96 / 72);
64178
+ }
64179
+ /**
64180
+ * Font families offered by the Home-tab font dropdown, alphabetically.
64181
+ *
64182
+ * Covers the families PowerPoint's own list leads with (the Office UI faces,
64183
+ * the Aptos family that replaced Calibri as the default theme font, and the
64184
+ * classic Windows/Mac core fonts) plus the handful of web faces decks
64185
+ * routinely arrive with. Entries the host cannot resolve simply fall back
64186
+ * through the CSS font stack, so listing a family costs nothing but gives the
64187
+ * user a name to pick when the deck already references it.
64188
+ */
64189
+ const COMMON_FONT_FAMILIES = [
64190
+ 'Abadi',
64191
+ 'Aptos',
64192
+ 'Aptos Display',
64193
+ 'Arial',
64194
+ 'Arial Black',
64195
+ 'Arial Narrow',
64196
+ 'Bahnschrift',
64197
+ 'Book Antiqua',
64198
+ 'Bookman Old Style',
64199
+ 'Calibri',
64200
+ 'Calibri Light',
64201
+ 'Cambria',
64202
+ 'Candara',
64203
+ 'Century Gothic',
64204
+ 'Comic Sans MS',
64205
+ 'Consolas',
64206
+ 'Corbel',
64207
+ 'Courier New',
64208
+ 'Franklin Gothic Book',
64209
+ 'Franklin Gothic Medium',
64210
+ 'Garamond',
64211
+ 'Georgia',
64212
+ 'Gill Sans MT',
64213
+ 'Helvetica',
64214
+ 'Impact',
64215
+ 'Inter',
64216
+ 'Lucida Console',
64217
+ 'Lucida Sans Unicode',
64218
+ 'Microsoft Sans Serif',
64219
+ 'Montserrat',
64220
+ 'Noto Sans',
64221
+ 'Open Sans',
64222
+ 'Palatino Linotype',
64223
+ 'Poppins',
64224
+ 'Roboto',
64225
+ 'Rockwell',
64226
+ 'Segoe UI',
64227
+ 'Source Sans Pro',
64228
+ 'Tahoma',
64229
+ 'Times New Roman',
64230
+ 'Trebuchet MS',
64231
+ 'Tw Cen MT',
64232
+ 'Verdana',
64233
+ ];
64234
+ /** Font sizes (pt) offered by the Home-tab size dropdown. */
64235
+ const COMMON_FONT_SIZES = [
64236
+ 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96,
64237
+ ];
64238
+ /** Character-spacing presets for the toolbar dropdown. */
64239
+ const CHARACTER_SPACING_OPTIONS = [
64240
+ { label: 'Very Tight', i18nKey: 'pptx.text.characterSpacingVeryTight', value: -150 },
64241
+ { label: 'Tight', i18nKey: 'pptx.text.characterSpacingTight', value: -75 },
64242
+ { label: 'Normal', i18nKey: 'pptx.text.characterSpacingNormal', value: 0 },
64243
+ { label: 'Loose', i18nKey: 'pptx.text.characterSpacingLoose', value: 75 },
64244
+ { label: 'Very Loose', i18nKey: 'pptx.text.characterSpacingVeryLoose', value: 150 },
64245
+ ];
64246
+ /** Line-spacing presets for the paragraph dropdown. */
64247
+ const LINE_SPACING_OPTIONS$1 = [
64248
+ { label: '1.0', value: 1.0 },
64249
+ { label: '1.15', value: 1.15 },
64250
+ { label: '1.5', value: 1.5 },
64251
+ { label: '2.0', value: 2.0 },
64252
+ { label: '2.5', value: 2.5 },
64253
+ { label: '3.0', value: 3.0 },
64254
+ ];
64255
+ /** Change-case options in menu order (matches PowerPoint's ordering). */
64256
+ const CHANGE_CASE_OPTIONS$1 = [
64257
+ { value: 'sentence', i18nKey: 'pptx.text.changeCaseSentence' },
64258
+ { value: 'lower', i18nKey: 'pptx.text.changeCaseLower' },
64259
+ { value: 'upper', i18nKey: 'pptx.text.changeCaseUpper' },
64260
+ { value: 'capitalize', i18nKey: 'pptx.text.changeCaseCapitalize' },
64261
+ { value: 'toggle', i18nKey: 'pptx.text.changeCaseToggle' },
64262
+ ];
64263
+
64264
+ /**
64265
+ * inspector-helpers.ts: Pure (no framework) helpers for the inspector panel.
64266
+ *
64267
+ * Readers extract display values from a PptxElement (with sensible defaults),
64268
+ * and patch builders produce shallow-merge-ready Partial<PptxElement> objects
64269
+ * for the binding's element-update path. Shared across React, Vue, and Angular.
64270
+ */
64271
+ const DEFAULT_FILL = '#ffffff';
64272
+ const DEFAULT_STROKE = '#000000';
64273
+ const DEFAULT_TEXT_COLOR = '#000000';
64274
+ /**
64275
+ * PowerPoint's own presentation-level default text style (`p:defaultTextStyle
64276
+ * /a:lvl1pPr/a:defRPr@sz`) is 1800 (18pt), so a shape with no explicit font
64277
+ * size renders at 18pt in real PowerPoint, not 12pt. Kept as the last-resort
64278
+ * fallback below the deck's actual default when {@link fontSizeOf} is given one.
64279
+ */
64280
+ const DEFAULT_FONT_SIZE$2 = 18;
64281
+ /**
64282
+ * Returns the fill colour of the element's shapeStyle, or a white default.
64283
+ * Only meaningful for elements that pass `hasShapeProperties`.
64284
+ */
64285
+ function fillColorOf$1(el) {
64286
+ if (hasShapeProperties(el)) {
64287
+ return el.shapeStyle?.fillColor ?? DEFAULT_FILL;
64288
+ }
64289
+ return DEFAULT_FILL;
64290
+ }
64291
+ /**
64292
+ * Returns the stroke colour of the element's shapeStyle, or a black default.
64293
+ * Only meaningful for elements that pass `hasShapeProperties`.
64294
+ */
64295
+ function strokeColorOf(el) {
64296
+ if (hasShapeProperties(el)) {
64297
+ return el.shapeStyle?.strokeColor ?? DEFAULT_STROKE;
64298
+ }
64299
+ return DEFAULT_STROKE;
64300
+ }
64301
+ /**
64302
+ * Returns the text colour from the element's textStyle, or a black default.
64303
+ * Only meaningful for elements that pass `hasTextProperties`.
64304
+ */
64305
+ function textColorOf(el) {
64306
+ if (hasTextProperties(el)) {
64307
+ return el.textStyle?.color ?? DEFAULT_TEXT_COLOR;
64308
+ }
64309
+ return DEFAULT_TEXT_COLOR;
64310
+ }
64311
+ /**
64312
+ * Returns the font size (in points) from the element's textStyle.
64313
+ *
64314
+ * Falls back, in order, to: the deck's presentation-level default text style
64315
+ * (`p:defaultTextStyle`, passed as `presentationDefault` when the caller has
64316
+ * one), then `DEFAULT_FONT_SIZE` (18pt, matching PowerPoint's own
64317
+ * `a:lvl1pPr/a:defRPr@sz="1800"` when neither is available).
64318
+ */
64319
+ function fontSizeOf(el, presentationDefault) {
64320
+ if (hasTextProperties(el) && el.textStyle?.fontSize !== undefined) {
64321
+ return textFontSizePxToPt(el.textStyle.fontSize);
64322
+ }
64323
+ const deckDefault = presentationDefault?.levelStyles?.[0]?.fontSize;
64324
+ return deckDefault === undefined ? DEFAULT_FONT_SIZE$2 : textFontSizePxToPt(deckDefault);
64325
+ }
64326
+ /** Returns whether the element's text is bold (false when absent). */
64327
+ function isBold(el) {
64328
+ if (hasTextProperties(el)) {
64329
+ return el.textStyle?.bold ?? false;
64330
+ }
64331
+ return false;
64332
+ }
64333
+ /** Returns whether the element's text is italic (false when absent). */
64334
+ function isItalic(el) {
64335
+ if (hasTextProperties(el)) {
64336
+ return el.textStyle?.italic ?? false;
64337
+ }
64338
+ return false;
64339
+ }
64340
+ /** Returns whether the element's text has underline (false when absent). */
64341
+ function isUnderline(el) {
64342
+ if (hasTextProperties(el)) {
64343
+ return el.textStyle?.underline ?? false;
64344
+ }
64345
+ return false;
64346
+ }
64347
+ /**
64348
+ * Builds a Partial<PptxElement> patch that merges the given changes into the
64349
+ * element's existing shapeStyle without dropping any other shapeStyle fields.
64350
+ */
64351
+ function shapeStylePatch$1(el, changes) {
64352
+ const base = hasShapeProperties(el) ? (el.shapeStyle ?? {}) : {};
64353
+ return {
64354
+ shapeStyle: {
64355
+ ...base,
64356
+ ...changes,
64357
+ },
64358
+ };
64359
+ }
64360
+ /**
64361
+ * Builds a Partial<PptxElement> patch that merges the given changes into the
64362
+ * element's existing textStyle without dropping any other textStyle fields.
64363
+ */
64364
+ function textStylePatch(el, changes) {
64365
+ const base = hasTextProperties(el) ? (el.textStyle ?? {}) : {};
64366
+ return {
64367
+ ...(hasTextProperties(el) && el.textSegments?.some((segment) => segment.paragraphInsertionStyle)
64368
+ ? {
64369
+ textSegments: el.textSegments.map((segment) => updateTextSegmentStyle(segment, changes, { updateBodyStyle: false })),
64370
+ }
64371
+ : {}),
64372
+ textStyle: {
64373
+ ...base,
64374
+ ...changes,
64375
+ },
64376
+ };
64377
+ }
64378
+ /** Apply an ordinary-text model pixel size to the element and all of its runs. */
64379
+ function textFontSizePatch(el, fontSize) {
64380
+ const patch = textStylePatch(el, { fontSize });
64381
+ if (!hasTextProperties(el) || !el.textSegments) {
64382
+ return patch;
64383
+ }
64384
+ return {
64385
+ ...patch,
64386
+ textSegments: el.textSegments.map((segment) => updateTextSegmentStyle(segment, { fontSize })),
64387
+ };
64388
+ }
64389
+
63990
64390
  /** Copy the paintable shape + text style off an element. */
63991
64391
  function copyFormatFromElement(element) {
63992
64392
  const result = {};
@@ -64063,10 +64463,7 @@ function applyFormatToElement(element, format) {
64063
64463
  if (format.textStyle && hasTextProperties(updated)) {
64064
64464
  updated = {
64065
64465
  ...updated,
64066
- textStyle: {
64067
- ...updated.textStyle,
64068
- ...definedEntries(format.textStyle),
64069
- },
64466
+ ...textStylePatch(updated, definedEntries(format.textStyle)),
64070
64467
  };
64071
64468
  }
64072
64469
  return updated;
@@ -64079,6 +64476,29 @@ function hasCopyableFormat(element) {
64079
64476
  return hasShapeProperties(element) || hasTextProperties(element);
64080
64477
  }
64081
64478
 
64479
+ /** Materialize typed body text without borrowing a display marker's style. */
64480
+ function remapEmptyParagraph(text, segments, terminator) {
64481
+ const source = segments[0] ?? terminator;
64482
+ const insertionStyle = source?.paragraphInsertionStyle;
64483
+ if (!source ||
64484
+ !insertionStyle ||
64485
+ segments.length > 1 ||
64486
+ (segments.length > 0 && source.text !== '' && !isBulletMarkerSegment(source))) {
64487
+ return undefined;
64488
+ }
64489
+ if (text.length === 0) {
64490
+ return segments.map((segment) => ({ ...segment }));
64491
+ }
64492
+ const first = { ...source };
64493
+ delete first.paragraphInsertionStyle;
64494
+ const bullet = first.bulletInfo;
64495
+ if (bullet && !bullet.none && segments.length > 0) {
64496
+ return [first, { text, style: { ...insertionStyle } }];
64497
+ }
64498
+ delete first.isParagraphBreak;
64499
+ return [{ ...first, text, style: { ...insertionStyle } }];
64500
+ }
64501
+
64082
64502
  /** Refresh only derived ordinals after existing paragraphs have moved. */
64083
64503
  function renumberRemappedParagraphs(segments) {
64084
64504
  const sequence = createAutoNumberSequence();
@@ -64138,21 +64558,23 @@ function withoutRenderedBulletPrefix(text, originalSegments, dedicatedMarker) {
64138
64558
  return withoutMarker;
64139
64559
  }
64140
64560
  /**
64141
- * Advance an appended paragraph from the final authored auto-numbered item.
64561
+ * Continue an inserted paragraph from the immediately preceding list item.
64142
64562
  * Core stores the list-relative ordinal as `paragraphIndex`; copying the final
64143
64563
  * item unchanged would render every paragraph added with Enter as the same
64144
64564
  * number. The literal marker is refreshed only when core supplied a dedicated
64145
64565
  * display-marker segment. The donor's list level is retained because core
64146
64566
  * sequences each level independently when the deck is reloaded. Other bullet
64147
- * kinds and auto-numbers without a known runtime index remain unchanged.
64567
+ * kinds retain their definition and level; unknown auto-number indices stay unknown.
64148
64568
  */
64149
- function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64569
+ function continueListParagraph(segments, donorSegments) {
64150
64570
  const donor = donorSegments[0];
64151
64571
  const paragraphIndex = donor?.bulletInfo?.paragraphIndex;
64152
- if (segments.length === 0 ||
64153
- !donor?.bulletInfo?.autoNumType ||
64154
- typeof paragraphIndex !== 'number' ||
64155
- !Number.isFinite(paragraphIndex)) {
64572
+ const bullet = resolveParagraphBullet(donor);
64573
+ if (segments.length === 0 || !bullet) {
64574
+ return segments;
64575
+ }
64576
+ if (bullet.isNumbered &&
64577
+ (typeof paragraphIndex !== 'number' || !Number.isFinite(paragraphIndex))) {
64156
64578
  return segments;
64157
64579
  }
64158
64580
  const [first, ...rest] = segments;
@@ -64160,13 +64582,18 @@ function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64160
64582
  ...first,
64161
64583
  bulletInfo: {
64162
64584
  ...donor.bulletInfo,
64163
- paragraphIndex: paragraphIndex + offset,
64585
+ ...(bullet.isNumbered && typeof paragraphIndex === 'number' && Number.isFinite(paragraphIndex)
64586
+ ? { paragraphIndex: paragraphIndex + 1 }
64587
+ : {}),
64164
64588
  },
64165
64589
  };
64166
64590
  if (donor.paragraphLevel !== undefined) {
64167
64591
  continued.paragraphLevel = donor.paragraphLevel;
64168
64592
  }
64169
- if (isBulletMarkerSegment(donor)) {
64593
+ if (bullet.isNumbered &&
64594
+ typeof paragraphIndex === 'number' &&
64595
+ Number.isFinite(paragraphIndex) &&
64596
+ isBulletMarkerSegment(donor)) {
64170
64597
  const resolved = resolveParagraphBullet(continued);
64171
64598
  if (resolved) {
64172
64599
  const trailingWhitespace = donor.text.match(/\s+$/u)?.[0] ?? '';
@@ -64176,6 +64603,37 @@ function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64176
64603
  return [continued, ...rest];
64177
64604
  }
64178
64605
 
64606
+ /**
64607
+ * Restore paragraph-scoped metadata on the first remapped run. Core and the
64608
+ * save writer deliberately carry these values on that run only; remapping the
64609
+ * characters must not turn an authored paragraph back into a default one.
64610
+ */
64611
+ function restoreParagraphMetadata(from, segments) {
64612
+ if (segments.length === 0) {
64613
+ return segments;
64614
+ }
64615
+ const [first, ...rest] = segments;
64616
+ const restored = { ...first };
64617
+ // `remapParagraph` may itself return a donor segment. Clear its paragraph
64618
+ // fields first so an extra paragraph cannot accidentally inherit metadata
64619
+ // merely because it reused the final paragraph for run styling.
64620
+ delete restored.paragraphLevel;
64621
+ delete restored.paragraphProperties;
64622
+ delete restored.endParaRunProperties;
64623
+ if (!from) {
64624
+ delete restored.paragraphInsertionStyle;
64625
+ }
64626
+ if (from?.paragraphLevel !== undefined) {
64627
+ restored.paragraphLevel = from.paragraphLevel;
64628
+ }
64629
+ if (from?.paragraphProperties !== undefined) {
64630
+ restored.paragraphProperties = from.paragraphProperties;
64631
+ }
64632
+ if (from?.endParaRunProperties !== undefined) {
64633
+ restored.endParaRunProperties = from.endParaRunProperties;
64634
+ }
64635
+ return [restored, ...rest];
64636
+ }
64179
64637
  function matches(text, paragraph) {
64180
64638
  const first = paragraph.segments[0];
64181
64639
  const marker = first &&
@@ -64283,6 +64741,9 @@ function isAtomicOriginalSegment(seg) {
64283
64741
  * style-level properties already survive via the copied `style` object.
64284
64742
  */
64285
64743
  function copySegmentMetadata(from, to) {
64744
+ if (!from) {
64745
+ return to;
64746
+ }
64286
64747
  if (from.equationXml !== undefined) {
64287
64748
  to.equationXml = from.equationXml;
64288
64749
  }
@@ -64303,39 +64764,11 @@ function copySegmentMetadata(from, to) {
64303
64764
  }
64304
64765
  return to;
64305
64766
  }
64306
- /**
64307
- * Restore paragraph-scoped metadata on the first remapped run. Core and the
64308
- * save writer deliberately carry these values on that run only; remapping the
64309
- * characters must not turn an authored paragraph back into a default one.
64310
- */
64311
- function restoreParagraphMetadata(from, segments) {
64312
- if (segments.length === 0) {
64313
- return segments;
64314
- }
64315
- const [first, ...rest] = segments;
64316
- const restored = { ...first };
64317
- // `remapParagraph` may itself return a donor segment. Clear its paragraph
64318
- // fields first so an extra paragraph cannot accidentally inherit metadata
64319
- // merely because it reused the final paragraph for run styling.
64320
- delete restored.paragraphLevel;
64321
- delete restored.paragraphProperties;
64322
- delete restored.endParaRunProperties;
64323
- if (from?.paragraphLevel !== undefined) {
64324
- restored.paragraphLevel = from.paragraphLevel;
64325
- }
64326
- if (from?.paragraphProperties !== undefined) {
64327
- restored.paragraphProperties = from.paragraphProperties;
64328
- }
64329
- if (from?.endParaRunProperties !== undefined) {
64330
- restored.endParaRunProperties = from.endParaRunProperties;
64331
- }
64332
- return [restored, ...rest];
64333
- }
64334
64767
  /**
64335
64768
  * Strategy:
64336
64769
  * 1. Split both original segments and new text into paragraphs by "\n".
64337
64770
  * 2. Distribute new characters proportionally across segments.
64338
- * 3. Extra chars go to last segment, extra paragraphs inherit last style.
64771
+ * 3. Extra chars go to the last segment; new paragraphs use their preceding context.
64339
64772
  * 4. Re-insert paragraph-break markers between paragraphs.
64340
64773
  */
64341
64774
  function remapTextToSegments(newText, originalSegments, elementTextStyle) {
@@ -64366,7 +64799,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64366
64799
  const baseFallbackStyle = firstContentSeg?.style
64367
64800
  ? { ...firstContentSeg.style }
64368
64801
  : fallbackStyle;
64369
- function remapParagraph(paraNewText, paraOrigSegments) {
64802
+ function remapParagraph(paraNewText, paraOrigSegments, isOriginalParagraph = true) {
64370
64803
  if (paraOrigSegments.length === 0) {
64371
64804
  return paraNewText.length > 0
64372
64805
  ? [{ text: paraNewText, style: { ...baseFallbackStyle } }]
@@ -64380,9 +64813,12 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64380
64813
  : undefined;
64381
64814
  if (dedicatedMarker) {
64382
64815
  const contentSegments = paraOrigSegments.slice(1);
64383
- const contentText = withoutRenderedBulletPrefix(paraNewText, paraOrigSegments, dedicatedMarker);
64816
+ // A new paragraph has no prior display marker to strip from authored text.
64817
+ const contentText = isOriginalParagraph
64818
+ ? withoutRenderedBulletPrefix(paraNewText, paraOrigSegments, dedicatedMarker)
64819
+ : paraNewText;
64384
64820
  const content = contentSegments.length > 0
64385
- ? remapParagraph(contentText, contentSegments)
64821
+ ? remapParagraph(contentText, contentSegments, isOriginalParagraph)
64386
64822
  : [{ text: contentText, style: { ...dedicatedMarker.style } }];
64387
64823
  return [dedicatedMarker, ...content];
64388
64824
  }
@@ -64398,7 +64834,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64398
64834
  const totalOrigLen = paraOrigSegments.reduce((sum, s) => sum + s.text.length, 0);
64399
64835
  if (totalOrigLen === 0) {
64400
64836
  const result = [
64401
- copySegmentMetadata(paraOrigSegments[0], {
64837
+ copySegmentMetadata(isOriginalParagraph ? paraOrigSegments[0] : undefined, {
64402
64838
  text: paraNewText,
64403
64839
  style: { ...paraOrigSegments[0].style },
64404
64840
  }),
@@ -64415,7 +64851,8 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64415
64851
  // An atomic (field/equation) segment never gets the "last segment
64416
64852
  // absorbs everything left over" treatment, even when it IS the last
64417
64853
  // segment - see `isAtomicOriginalSegment`.
64418
- const isLastSeg = i === paraOrigSegments.length - 1 && !isAtomicOriginalSegment(origSeg);
64854
+ const isLastSeg = i === paraOrigSegments.length - 1 &&
64855
+ (!isOriginalParagraph || !isAtomicOriginalSegment(origSeg));
64419
64856
  const origLen = origSeg.text.length;
64420
64857
  if (newPos >= paraNewText.length) {
64421
64858
  break;
@@ -64428,7 +64865,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64428
64865
  segText = paraNewText.slice(newPos, newPos + origLen);
64429
64866
  }
64430
64867
  if (segText.length > 0) {
64431
- const outSeg = copySegmentMetadata(origSeg, {
64868
+ const outSeg = copySegmentMetadata(isOriginalParagraph ? origSeg : undefined, {
64432
64869
  text: segText,
64433
64870
  style: { ...origSeg.style },
64434
64871
  });
@@ -64452,7 +64889,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64452
64889
  });
64453
64890
  }
64454
64891
  if (remapped.length === 0) {
64455
- const fallback = copySegmentMetadata(paraOrigSegments[0], {
64892
+ const fallback = copySegmentMetadata(isOriginalParagraph ? paraOrigSegments[0] : undefined, {
64456
64893
  text: paraNewText,
64457
64894
  style: { ...paraOrigSegments[0].style },
64458
64895
  });
@@ -64465,27 +64902,30 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64465
64902
  }
64466
64903
  const output = [];
64467
64904
  const lastOrigPara = originalParagraphs[originalParagraphs.length - 1]?.segments;
64468
- const lastSourceOffset = [...paragraphSources]
64469
- .reverse()
64470
- .findIndex((source) => source !== undefined);
64471
- const appendStart = Math.max(originalParagraphs.length, lastSourceOffset < 0 ? 0 : paragraphSources.length - lastSourceOffset);
64905
+ let precedingParagraph;
64472
64906
  for (let pi = 0; pi < newParagraphTexts.length; pi++) {
64473
64907
  if (pi > 0) {
64474
64908
  const precedingOrigPara = originalParagraphs[paragraphSources[pi - 1] ?? -1]?.segments ?? [];
64475
64909
  const breakStyle = precedingOrigPara[0]?.style
64476
64910
  ? { ...precedingOrigPara[0].style }
64477
64911
  : { ...baseFallbackStyle };
64478
- output.push({ text: '\n', style: breakStyle, isParagraphBreak: true });
64912
+ const terminator = originalParagraphs[paragraphSources[pi - 1] ?? -1]?.terminator;
64913
+ output.push(terminator?.paragraphInsertionStyle && newParagraphTexts[pi - 1] === ''
64914
+ ? { ...terminator, text: '\n', isParagraphBreak: true }
64915
+ : { text: '\n', style: breakStyle, isParagraphBreak: true });
64479
64916
  }
64480
64917
  const originalParagraph = originalParagraphs[paragraphSources[pi] ?? -1];
64481
- const origPara = originalParagraph?.segments ?? lastOrigPara ?? [];
64482
- let paraSegments = restoreParagraphMetadata(originalParagraph?.segments[0] ?? originalParagraph?.terminator, remapParagraph(newParagraphTexts[pi], origPara));
64483
- // Only true tail appends use the historical numbering continuation rule.
64484
- // An unmatched middle paragraph has no donor paragraph metadata.
64485
- if (!originalParagraph && pi >= appendStart) {
64486
- paraSegments = continueAutoNumberedParagraph(paraSegments, lastOrigPara ?? [], pi - originalParagraphs.length + 1);
64918
+ const origPara = originalParagraph?.segments ?? precedingParagraph ?? lastOrigPara ?? [];
64919
+ let paraSegments = restoreParagraphMetadata(originalParagraph?.segments[0] ?? originalParagraph?.terminator, (originalParagraph &&
64920
+ remapEmptyParagraph(newParagraphTexts[pi], origPara, originalParagraph.terminator)) ??
64921
+ remapParagraph(newParagraphTexts[pi], origPara, originalParagraph !== undefined));
64922
+ // New items follow their local list, without inheriting paragraph spacing
64923
+ // or end-run properties reserved for an aligned original paragraph.
64924
+ if (!originalParagraph && precedingParagraph) {
64925
+ paraSegments = continueListParagraph(paraSegments, precedingParagraph);
64487
64926
  }
64488
64927
  output.push(...paraSegments);
64928
+ precedingParagraph = paraSegments;
64489
64929
  }
64490
64930
  if (paragraphSources.some((source, index) => source !== undefined && source !== index)) {
64491
64931
  return renumberRemappedParagraphs(output);
@@ -66143,6 +66583,9 @@ function buildSegmentAttrs(seg) {
66143
66583
  if (seg.endParaRunProperties) {
66144
66584
  a.pr = JSON.stringify(seg.endParaRunProperties);
66145
66585
  }
66586
+ if (seg.paragraphInsertionStyle) {
66587
+ a.pi = JSON.stringify(seg.paragraphInsertionStyle);
66588
+ }
66146
66589
  if (typeof seg.fieldType === 'string') {
66147
66590
  a.ft = seg.fieldType;
66148
66591
  }
@@ -66268,6 +66711,14 @@ function decodeDelta(delta) {
66268
66711
  /* skip */
66269
66712
  }
66270
66713
  }
66714
+ if (a.pi) {
66715
+ try {
66716
+ seg.paragraphInsertionStyle = JSON.parse(a.pi);
66717
+ }
66718
+ catch {
66719
+ /* skip */
66720
+ }
66721
+ }
66271
66722
  if (a.ft) {
66272
66723
  seg.fieldType = a.ft;
66273
66724
  }
@@ -66501,6 +66952,7 @@ const COMPLEX_ELEMENT_FIELDS = {
66501
66952
  children: '_ch',
66502
66953
  paragraphIndents: '_pi',
66503
66954
  rawXml: '_rx',
66955
+ inheritedTransform: '_it',
66504
66956
  extLstXml: '_elx',
66505
66957
  actionClick: '_ac',
66506
66958
  actionHover: '_av',
@@ -77556,229 +78008,6 @@ function smartArtNodeLabel(node) {
77556
78008
  };
77557
78009
  }
77558
78010
 
77559
- /**
77560
- * Regular-text font sizes are stored in slide/CSS pixels in the shared model,
77561
- * while PowerPoint's font controls and the preset list below use points.
77562
- */
77563
- function textFontSizePxToPt(fontSizePx) {
77564
- // DrawingML stores regular text sizes in hundredths of a point. Normalising
77565
- // to that precision removes binary floating-point noise without discarding
77566
- // valid authored values such as 10.5 pt or 48.1 pt.
77567
- return Math.round(fontSizePx * (72 / 96) * 100) / 100;
77568
- }
77569
- /** Convert a PowerPoint font-control value in points to the model's pixels. */
77570
- function textFontSizePtToPx(fontSizePt) {
77571
- return fontSizePt * (96 / 72);
77572
- }
77573
- /**
77574
- * Font families offered by the Home-tab font dropdown, alphabetically.
77575
- *
77576
- * Covers the families PowerPoint's own list leads with (the Office UI faces,
77577
- * the Aptos family that replaced Calibri as the default theme font, and the
77578
- * classic Windows/Mac core fonts) plus the handful of web faces decks
77579
- * routinely arrive with. Entries the host cannot resolve simply fall back
77580
- * through the CSS font stack, so listing a family costs nothing but gives the
77581
- * user a name to pick when the deck already references it.
77582
- */
77583
- const COMMON_FONT_FAMILIES = [
77584
- 'Abadi',
77585
- 'Aptos',
77586
- 'Aptos Display',
77587
- 'Arial',
77588
- 'Arial Black',
77589
- 'Arial Narrow',
77590
- 'Bahnschrift',
77591
- 'Book Antiqua',
77592
- 'Bookman Old Style',
77593
- 'Calibri',
77594
- 'Calibri Light',
77595
- 'Cambria',
77596
- 'Candara',
77597
- 'Century Gothic',
77598
- 'Comic Sans MS',
77599
- 'Consolas',
77600
- 'Corbel',
77601
- 'Courier New',
77602
- 'Franklin Gothic Book',
77603
- 'Franklin Gothic Medium',
77604
- 'Garamond',
77605
- 'Georgia',
77606
- 'Gill Sans MT',
77607
- 'Helvetica',
77608
- 'Impact',
77609
- 'Inter',
77610
- 'Lucida Console',
77611
- 'Lucida Sans Unicode',
77612
- 'Microsoft Sans Serif',
77613
- 'Montserrat',
77614
- 'Noto Sans',
77615
- 'Open Sans',
77616
- 'Palatino Linotype',
77617
- 'Poppins',
77618
- 'Roboto',
77619
- 'Rockwell',
77620
- 'Segoe UI',
77621
- 'Source Sans Pro',
77622
- 'Tahoma',
77623
- 'Times New Roman',
77624
- 'Trebuchet MS',
77625
- 'Tw Cen MT',
77626
- 'Verdana',
77627
- ];
77628
- /** Font sizes (pt) offered by the Home-tab size dropdown. */
77629
- const COMMON_FONT_SIZES = [
77630
- 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96,
77631
- ];
77632
- /** Character-spacing presets for the toolbar dropdown. */
77633
- const CHARACTER_SPACING_OPTIONS = [
77634
- { label: 'Very Tight', i18nKey: 'pptx.text.characterSpacingVeryTight', value: -150 },
77635
- { label: 'Tight', i18nKey: 'pptx.text.characterSpacingTight', value: -75 },
77636
- { label: 'Normal', i18nKey: 'pptx.text.characterSpacingNormal', value: 0 },
77637
- { label: 'Loose', i18nKey: 'pptx.text.characterSpacingLoose', value: 75 },
77638
- { label: 'Very Loose', i18nKey: 'pptx.text.characterSpacingVeryLoose', value: 150 },
77639
- ];
77640
- /** Line-spacing presets for the paragraph dropdown. */
77641
- const LINE_SPACING_OPTIONS$1 = [
77642
- { label: '1.0', value: 1.0 },
77643
- { label: '1.15', value: 1.15 },
77644
- { label: '1.5', value: 1.5 },
77645
- { label: '2.0', value: 2.0 },
77646
- { label: '2.5', value: 2.5 },
77647
- { label: '3.0', value: 3.0 },
77648
- ];
77649
- /** Change-case options in menu order (matches PowerPoint's ordering). */
77650
- const CHANGE_CASE_OPTIONS$1 = [
77651
- { value: 'sentence', i18nKey: 'pptx.text.changeCaseSentence' },
77652
- { value: 'lower', i18nKey: 'pptx.text.changeCaseLower' },
77653
- { value: 'upper', i18nKey: 'pptx.text.changeCaseUpper' },
77654
- { value: 'capitalize', i18nKey: 'pptx.text.changeCaseCapitalize' },
77655
- { value: 'toggle', i18nKey: 'pptx.text.changeCaseToggle' },
77656
- ];
77657
-
77658
- /**
77659
- * inspector-helpers.ts: Pure (no framework) helpers for the inspector panel.
77660
- *
77661
- * Readers extract display values from a PptxElement (with sensible defaults),
77662
- * and patch builders produce shallow-merge-ready Partial<PptxElement> objects
77663
- * for the binding's element-update path. Shared across React, Vue, and Angular.
77664
- */
77665
- const DEFAULT_FILL = '#ffffff';
77666
- const DEFAULT_STROKE = '#000000';
77667
- const DEFAULT_TEXT_COLOR = '#000000';
77668
- /**
77669
- * PowerPoint's own presentation-level default text style (`p:defaultTextStyle
77670
- * /a:lvl1pPr/a:defRPr@sz`) is 1800 (18pt), so a shape with no explicit font
77671
- * size renders at 18pt in real PowerPoint, not 12pt. Kept as the last-resort
77672
- * fallback below the deck's actual default when {@link fontSizeOf} is given one.
77673
- */
77674
- const DEFAULT_FONT_SIZE$2 = 18;
77675
- /**
77676
- * Returns the fill colour of the element's shapeStyle, or a white default.
77677
- * Only meaningful for elements that pass `hasShapeProperties`.
77678
- */
77679
- function fillColorOf$1(el) {
77680
- if (hasShapeProperties(el)) {
77681
- return el.shapeStyle?.fillColor ?? DEFAULT_FILL;
77682
- }
77683
- return DEFAULT_FILL;
77684
- }
77685
- /**
77686
- * Returns the stroke colour of the element's shapeStyle, or a black default.
77687
- * Only meaningful for elements that pass `hasShapeProperties`.
77688
- */
77689
- function strokeColorOf(el) {
77690
- if (hasShapeProperties(el)) {
77691
- return el.shapeStyle?.strokeColor ?? DEFAULT_STROKE;
77692
- }
77693
- return DEFAULT_STROKE;
77694
- }
77695
- /**
77696
- * Returns the text colour from the element's textStyle, or a black default.
77697
- * Only meaningful for elements that pass `hasTextProperties`.
77698
- */
77699
- function textColorOf(el) {
77700
- if (hasTextProperties(el)) {
77701
- return el.textStyle?.color ?? DEFAULT_TEXT_COLOR;
77702
- }
77703
- return DEFAULT_TEXT_COLOR;
77704
- }
77705
- /**
77706
- * Returns the font size (in points) from the element's textStyle.
77707
- *
77708
- * Falls back, in order, to: the deck's presentation-level default text style
77709
- * (`p:defaultTextStyle`, passed as `presentationDefault` when the caller has
77710
- * one), then `DEFAULT_FONT_SIZE` (18pt, matching PowerPoint's own
77711
- * `a:lvl1pPr/a:defRPr@sz="1800"` when neither is available).
77712
- */
77713
- function fontSizeOf(el, presentationDefault) {
77714
- if (hasTextProperties(el) && el.textStyle?.fontSize !== undefined) {
77715
- return textFontSizePxToPt(el.textStyle.fontSize);
77716
- }
77717
- const deckDefault = presentationDefault?.levelStyles?.[0]?.fontSize;
77718
- return deckDefault === undefined ? DEFAULT_FONT_SIZE$2 : textFontSizePxToPt(deckDefault);
77719
- }
77720
- /** Returns whether the element's text is bold (false when absent). */
77721
- function isBold(el) {
77722
- if (hasTextProperties(el)) {
77723
- return el.textStyle?.bold ?? false;
77724
- }
77725
- return false;
77726
- }
77727
- /** Returns whether the element's text is italic (false when absent). */
77728
- function isItalic(el) {
77729
- if (hasTextProperties(el)) {
77730
- return el.textStyle?.italic ?? false;
77731
- }
77732
- return false;
77733
- }
77734
- /** Returns whether the element's text has underline (false when absent). */
77735
- function isUnderline(el) {
77736
- if (hasTextProperties(el)) {
77737
- return el.textStyle?.underline ?? false;
77738
- }
77739
- return false;
77740
- }
77741
- /**
77742
- * Builds a Partial<PptxElement> patch that merges the given changes into the
77743
- * element's existing shapeStyle without dropping any other shapeStyle fields.
77744
- */
77745
- function shapeStylePatch$1(el, changes) {
77746
- const base = hasShapeProperties(el) ? (el.shapeStyle ?? {}) : {};
77747
- return {
77748
- shapeStyle: {
77749
- ...base,
77750
- ...changes,
77751
- },
77752
- };
77753
- }
77754
- /**
77755
- * Builds a Partial<PptxElement> patch that merges the given changes into the
77756
- * element's existing textStyle without dropping any other textStyle fields.
77757
- */
77758
- function textStylePatch(el, changes) {
77759
- const base = hasTextProperties(el) ? (el.textStyle ?? {}) : {};
77760
- return {
77761
- textStyle: {
77762
- ...base,
77763
- ...changes,
77764
- },
77765
- };
77766
- }
77767
- /** Apply an ordinary-text model pixel size to the element and all of its runs. */
77768
- function textFontSizePatch(el, fontSize) {
77769
- const patch = textStylePatch(el, { fontSize });
77770
- if (!hasTextProperties(el) || !el.textSegments) {
77771
- return patch;
77772
- }
77773
- return {
77774
- ...patch,
77775
- textSegments: el.textSegments.map((segment) => ({
77776
- ...segment,
77777
- style: { ...segment.style, fontSize },
77778
- })),
77779
- };
77780
- }
77781
-
77782
78011
  /**
77783
78012
  * effects-shadow-helpers.ts: Pure (no framework) outer/inner shadow helpers
77784
78013
  * for the effects panel.
@@ -80918,7 +81147,7 @@ function zoomOutPercent(percent) {
80918
81147
  *
80919
81148
  * The model here is one thing:
80920
81149
  * - `zoom` is the USER's factor, where 1 means "whatever fits".
80921
- * - `fitScale` is the viewport measurement the binding feeds in (<= 1).
81150
+ * - `fitScale` is the positive viewport measurement the binding feeds in.
80922
81151
  * - `manual` records whether the user has taken control, which is what
80923
81152
  * separates "reset to 100%" from "fit to viewport" without needing a
80924
81153
  * sentinel value smuggled into the number.
@@ -82942,10 +83171,40 @@ function buildElementClipboardPayload(element, isTemplate) {
82942
83171
  function cloneElementForPaste(element, options = {}) {
82943
83172
  const clone = structuredClone(element);
82944
83173
  const intoTemplate = options.intoTemplate ?? false;
82945
- clone.id = makeCloneId(intoTemplate, element.id);
83174
+ const modelIds = new Map();
83175
+ const nativeIds = new Map();
83176
+ const mintId = (node) => {
83177
+ const id = makeCloneId(intoTemplate, element.id);
83178
+ modelIds.set(node.id, id);
83179
+ if (node.shapeId !== undefined) {
83180
+ nativeIds.set(node.shapeId, id);
83181
+ }
83182
+ // A clone is a new native shape too; save allocates IDs for its targets.
83183
+ delete node.shapeId;
83184
+ return id;
83185
+ };
83186
+ clone.id = mintId(clone);
82946
83187
  // The root's ORIGINAL id decides the template store for the whole subtree,
82947
83188
  // so a descendant that carries no prefix of its own cannot vote it elsewhere.
82948
- reassignDescendantIds(clone, () => makeCloneId(intoTemplate, element.id));
83189
+ reassignDescendantIds(clone, mintId);
83190
+ const remapConnections = (node) => {
83191
+ if (node.type === 'group') {
83192
+ node.children.forEach(remapConnections);
83193
+ }
83194
+ if (node.type !== 'connector') {
83195
+ return;
83196
+ }
83197
+ for (const ref of [
83198
+ node.shapeStyle?.connectorStartConnection,
83199
+ node.shapeStyle?.connectorEndConnection,
83200
+ ]) {
83201
+ if (!ref?.shapeId) {
83202
+ continue;
83203
+ }
83204
+ ref.shapeId = modelIds.get(ref.shapeId) ?? nativeIds.get(ref.shapeId) ?? ref.shapeId;
83205
+ }
83206
+ };
83207
+ remapConnections(clone);
82949
83208
  clone.x += options.offsetX ?? PASTE_OFFSET_PX;
82950
83209
  clone.y += options.offsetY ?? PASTE_OFFSET_PX;
82951
83210
  return clone;
@@ -83398,6 +83657,7 @@ const GUARD_DEFAULTS$1 = {
83398
83657
  canEdit: true,
83399
83658
  isPresenting: false,
83400
83659
  hasSelection: false,
83660
+ canPaste: true,
83401
83661
  isEditingText: false,
83402
83662
  isDrawing: false,
83403
83663
  isTextInputTarget: false,
@@ -83499,6 +83759,9 @@ function mapEditorKey(input, guard = {}) {
83499
83759
  if (mod && !alt) {
83500
83760
  const chord = resolveChord(key, Boolean(input.shiftKey), state.hasSelection);
83501
83761
  if (chord) {
83762
+ if (chord.action === 'paste' && state.canPaste === false) {
83763
+ return NO_ACTION$1;
83764
+ }
83502
83765
  return chord;
83503
83766
  }
83504
83767
  }
@@ -89985,6 +90248,17 @@ const COMMON_FONTS = [
89985
90248
  'Verdana',
89986
90249
  ];
89987
90250
 
90251
+ /** Prepare a caller-owned model for insertion into an ordinary editable slide. */
90252
+ function prepareElementForInsertion(element, target) {
90253
+ if (!target.canEdit ||
90254
+ target.mode !== 'edit' ||
90255
+ !target.hasActiveSlide ||
90256
+ target.editTemplateMode) {
90257
+ return undefined;
90258
+ }
90259
+ return cloneElementForPaste(element, { offsetX: 0, offsetY: 0 });
90260
+ }
90261
+
89988
90262
  /**
89989
90263
  * Clone a `PptxHeaderFooter` into a fresh draft object for the Header & Footer
89990
90264
  * dialog to mutate locally, without touching the committed value until the
@@ -96088,10 +96362,19 @@ function resolveSlideSizeRescaleTransform(oldSize, newSize, mode) {
96088
96362
  }
96089
96363
  /** Scale every font size an element's own text style carries, in place on a shallow copy. */
96090
96364
  function scaleTextSegment(segment, scale) {
96091
- if (typeof segment.style.fontSize !== 'number') {
96365
+ const insertion = segment.paragraphInsertionStyle;
96366
+ if (typeof segment.style.fontSize !== 'number' && typeof insertion?.fontSize !== 'number') {
96092
96367
  return segment;
96093
96368
  }
96094
- return { ...segment, style: { ...segment.style, fontSize: segment.style.fontSize * scale } };
96369
+ return {
96370
+ ...segment,
96371
+ ...(typeof segment.style.fontSize === 'number'
96372
+ ? { style: { ...segment.style, fontSize: segment.style.fontSize * scale } }
96373
+ : {}),
96374
+ ...(typeof insertion?.fontSize === 'number'
96375
+ ? { paragraphInsertionStyle: { ...insertion, fontSize: insertion.fontSize * scale } }
96376
+ : {}),
96377
+ };
96095
96378
  }
96096
96379
  /**
96097
96380
  * Scale an element's font sizes (its own `textStyle.fontSize` and every
@@ -97464,6 +97747,62 @@ function wrapForeignObjectSvg(bodyMarkup, tile) {
97464
97747
  `viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}">${bodyMarkup}</svg>`);
97465
97748
  }
97466
97749
 
97750
+ const DEFAULTS$1 = {
97751
+ fitPadding: { horizontal: 0, vertical: 0 },
97752
+ maxFitScale: null,
97753
+ };
97754
+ function validPadding(value, fallback) {
97755
+ return Number.isFinite(value) && value >= 0 ? value : fallback;
97756
+ }
97757
+ /** Normalize once for both fit measurement and a binding's physical viewport CSS. */
97758
+ function resolveViewportFitOptions(options = {}, defaults = DEFAULTS$1) {
97759
+ const base = typeof defaults.fitPadding === 'number'
97760
+ ? { horizontal: defaults.fitPadding, vertical: defaults.fitPadding }
97761
+ : defaults.fitPadding;
97762
+ const padding = options.fitPadding ?? base;
97763
+ const horizontal = typeof padding === 'number' ? padding : padding.horizontal;
97764
+ const vertical = typeof padding === 'number' ? padding : padding.vertical;
97765
+ const cap = options.maxFitScale;
97766
+ return {
97767
+ fitPadding: {
97768
+ horizontal: validPadding(horizontal, base.horizontal),
97769
+ vertical: validPadding(vertical, base.vertical),
97770
+ },
97771
+ maxFitScale: cap === null
97772
+ ? null
97773
+ : typeof cap === 'number' && Number.isFinite(cap) && cap > 0
97774
+ ? cap
97775
+ : defaults.maxFitScale,
97776
+ };
97777
+ }
97778
+ /** Calculate fit only: the user's zoom factor is applied separately by the viewer. */
97779
+ function calculateViewportFit(input, defaults = DEFAULTS$1) {
97780
+ const { fitPadding, maxFitScale } = resolveViewportFitOptions(input, defaults);
97781
+ const availableWidth = Math.max(0, validPadding(input.viewportWidth, 0) -
97782
+ 2 * fitPadding.horizontal -
97783
+ validPadding(input.horizontalGutter ?? 0, 0));
97784
+ const availableHeight = Math.max(0, validPadding(input.viewportHeight, 0) -
97785
+ 2 * fitPadding.vertical -
97786
+ validPadding(input.verticalGutter ?? 0, 0));
97787
+ const fallback = typeof input.fallbackScale === 'number' &&
97788
+ Number.isFinite(input.fallbackScale) &&
97789
+ input.fallbackScale > 0
97790
+ ? input.fallbackScale
97791
+ : 1;
97792
+ const validCanvas = Number.isFinite(input.canvasWidth) &&
97793
+ input.canvasWidth > 0 &&
97794
+ Number.isFinite(input.canvasHeight) &&
97795
+ input.canvasHeight > 0;
97796
+ const scale = availableWidth > 0 && availableHeight > 0 && validCanvas
97797
+ ? Math.min(availableWidth / input.canvasWidth, availableHeight / input.canvasHeight, maxFitScale ?? Number.POSITIVE_INFINITY)
97798
+ : fallback;
97799
+ return {
97800
+ scale: Number.isFinite(scale) && scale > 0 ? scale : fallback,
97801
+ availableWidth,
97802
+ availableHeight,
97803
+ };
97804
+ }
97805
+
97467
97806
  /**
97468
97807
  * Framework-agnostic rendering & editing helpers shared by the React, Vue, and
97469
97808
  * Angular `pptx-viewer` bindings. Pure TypeScript (no framework imports) — each
@@ -103684,7 +104023,7 @@ function createLocalStorageBackend(namespace) {
103684
104023
  /** Try IndexedDB first; fall back to localStorage on any failure. */
103685
104024
  async function resolveBackend(dbName, namespace) {
103686
104025
  try {
103687
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-B-Z8kwp1.mjs');
104026
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-B_pq-wB6.mjs');
103688
104027
  const db = await openChatDb(dbName);
103689
104028
  return createIdbBackend(db);
103690
104029
  }
@@ -104421,10 +104760,7 @@ function applyTextUpdate(el, u) {
104421
104760
  // visibly restyles instead of only the (unused) element-level fallback.
104422
104761
  textEl.textStyle = { ...textEl.textStyle, ...textStyle };
104423
104762
  if (textEl.textSegments) {
104424
- textEl.textSegments = textEl.textSegments.map((seg) => ({
104425
- ...seg,
104426
- style: { ...seg.style, ...textStyle },
104427
- }));
104763
+ textEl.textSegments = textEl.textSegments.map((seg) => updateTextSegmentStyle(seg, textStyle));
104428
104764
  }
104429
104765
  }
104430
104766
  /** Apply fill/stroke updates when the element carries a shape style. */
@@ -114084,8 +114420,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
114084
114420
 
114085
114421
  /**
114086
114422
  * canvas-fit.service.ts: Auto-fit scale measurement for `SlideCanvasComponent`.
114087
- * Computes the largest scale (<= 1) at which the whole slide fits its scroll
114088
- * viewport, reserving the 1rem gutter + drop shadow, so the parent's `zoom`
114423
+ * Computes the largest scale (capped at 1 by default) fitting its scroll
114424
+ * viewport, reserving host-configurable decorative padding, so the parent's `zoom`
114089
114425
  * input means "100% of fit" rather than "100% of the authored slide size".
114090
114426
  * Thumbnail consumers (slides panel, slide sorter) set `autoFit` false and
114091
114427
  * manage their own scale via `zoom` instead.
@@ -114101,7 +114437,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
114101
114437
  class CanvasFitService {
114102
114438
  constructor() {
114103
114439
  /**
114104
- * Auto-fit scale (<= 1): how much the fixed-size slide must shrink to fit
114440
+ * Auto-fit scale (capped at 1 by default): how the fixed-size slide fits
114105
114441
  * the scroll viewport. The authored slide is e.g. 1280x720, which overflows
114106
114442
  * a phone; without this it renders off-screen at `zoom=1`.
114107
114443
  */
@@ -114134,14 +114470,14 @@ class CanvasFitService {
114134
114470
  this.fitScale.set(1);
114135
114471
  return;
114136
114472
  }
114137
- const availW = Math.max(el.clientWidth - 16, 0);
114138
- const availH = Math.max(el.clientHeight - 32, 0);
114139
- if (!availW || !availH) {
114140
- this.fitScale.set(1);
114141
- return;
114142
- }
114143
- const fit = Math.min(availW / size.width, availH / size.height, 1);
114144
- this.fitScale.set(fit > 0 ? fit : 1);
114473
+ const fit = calculateViewportFit({
114474
+ viewportWidth: el.clientWidth,
114475
+ viewportHeight: el.clientHeight,
114476
+ canvasWidth: size.width,
114477
+ canvasHeight: size.height,
114478
+ ...this.host.fitOptions?.(),
114479
+ }, { fitPadding: { horizontal: 8, vertical: 16 }, maxFitScale: 1 });
114480
+ this.fitScale.set(fit.scale);
114145
114481
  }
114146
114482
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CanvasFitService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
114147
114483
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CanvasFitService }); }
@@ -123758,6 +124094,12 @@ class SlideCanvasComponent {
123758
124094
  ...(ngDevMode ? [{ debugName: "mediaDataUrls" }] : /* istanbul ignore next */ []));
123759
124095
  this.zoom = input(1, /* @ts-ignore */
123760
124096
  ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
124097
+ /** Unscaled padding on each side; omission keeps the existing fit allowance. */
124098
+ this.fitPadding = input(undefined, /* @ts-ignore */
124099
+ ...(ngDevMode ? [{ debugName: "fitPadding" }] : /* istanbul ignore next */ []));
124100
+ /** Fit-factor ceiling, independent of user zoom; null permits enlargement. */
124101
+ this.maxFitScale = input(undefined, /* @ts-ignore */
124102
+ ...(ngDevMode ? [{ debugName: "maxFitScale" }] : /* istanbul ignore next */ []));
123761
124103
  /** When true, elements are selectable and drag/resize handles are shown. */
123762
124104
  this.editable = input(false, /* @ts-ignore */
123763
124105
  ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
@@ -124307,10 +124649,13 @@ class SlideCanvasComponent {
124307
124649
  autoFit: () => this.autoFit(),
124308
124650
  viewportElement: () => this.viewportRef()?.nativeElement,
124309
124651
  canvasSize: () => this.canvasSize(),
124652
+ fitOptions: () => ({ fitPadding: this.fitPadding(), maxFitScale: this.maxFitScale() }),
124310
124653
  });
124311
124654
  // Re-fit whenever the authored slide size changes (e.g. switching decks).
124312
124655
  effect(() => {
124313
124656
  this.canvasSize();
124657
+ this.fitPadding();
124658
+ this.maxFitScale();
124314
124659
  this.canvasFit.recompute();
124315
124660
  });
124316
124661
  // Keep every delegated element renderer aligned with the shared role/name
@@ -124990,7 +125335,7 @@ class SlideCanvasComponent {
124990
125335
  }
124991
125336
  }
124992
125337
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
124993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", 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 }, rulerUnit: { classPropertyName: "rulerUnit", publicName: "rulerUnit", 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 }, gridSpacing: { classPropertyName: "gridSpacing", publicName: "gridSpacing", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, transparentBackground: { classPropertyName: "transparentBackground", publicName: "transparentBackground", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, exposeElementIds: { classPropertyName: "exposeElementIds", publicName: "exposeElementIds", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", transformEnd: "transformEnd", adjustUpdate: "adjustUpdate", connectorEndpointUpdate: "connectorEndpointUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textInput: "textInput", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
125338
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, fitPadding: { classPropertyName: "fitPadding", publicName: "fitPadding", isSignal: true, isRequired: false, transformFunction: null }, maxFitScale: { classPropertyName: "maxFitScale", publicName: "maxFitScale", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", 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 }, rulerUnit: { classPropertyName: "rulerUnit", publicName: "rulerUnit", 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 }, gridSpacing: { classPropertyName: "gridSpacing", publicName: "gridSpacing", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, transparentBackground: { classPropertyName: "transparentBackground", publicName: "transparentBackground", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, exposeElementIds: { classPropertyName: "exposeElementIds", publicName: "exposeElementIds", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", transformEnd: "transformEnd", adjustUpdate: "adjustUpdate", connectorEndpointUpdate: "connectorEndpointUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textInput: "textInput", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
124994
125339
  CanvasFitService,
124995
125340
  InkDrawingService,
124996
125341
  RulerGuidesService,
@@ -125018,7 +125363,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
125018
125363
  AiChangeOverlayComponent,
125019
125364
  ActiveXControlsOverlayComponent,
125020
125365
  ], template: "<div\n\t#viewport\n\tclass=\"pptx-ng-canvas-viewport\"\n\t[attr.data-pptx-viewport]=\"interactive() ? '' : null\"\n\t(pointerdown)=\"onViewportPointerDown($event)\"\n>\n\t<div class=\"pptx-ng-canvas-wrapper\" [ngStyle]=\"wrapperStyle()\">\n\t\t<div\n\t\t\t#stage\n\t\t\tclass=\"pptx-ng-canvas-stage\"\n\t\t\t[class.is-editable]=\"editable()\"\n\t\t\trole=\"region\"\n\t\t\t[attr.aria-roledescription]=\"interactive() || presenting() ? 'slide' : null\"\n\t\t\t[attr.data-pptx-ai-active]=\"aiActive() ? 'true' : null\"\n\t\t\t[ngStyle]=\"stageStyle()\"\n\t\t\t(pointerdown)=\"onStagePointerDown($event)\"\n\t\t\t(contextmenu)=\"onContextMenu($event)\"\n\t\t\t(dblclick)=\"onDblClick($event)\"\n\t\t>\n\t\t\t<!--\n\t\t\t\tTemplate layer: inherited master/layout elements, rendered BEHIND\n\t\t\t\tthe slide's own elements (lower z-index). Interactive + given the\n\t\t\t\tamber editable affordance only while editTemplateMode is on; when\n\t\t\t\toff they render inertly with no affordance, exactly as core\n\t\t\t\tdelivered them. `marked` keeps the data-pptx-element contract on\n\t\t\t\tthem even while locked: the marker means \"rendered slide element\",\n\t\t\t\tnot \"editable right now\".\n\t\t\t-->\n\t\t\t@for (element of visibleTemplateElements(); track element.id; let i = $index) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"element\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"i\"\n\t\t\t\t\t[obstacles]=\"connectorObstacles()\"\n\t\t\t\t\t[canvasWidth]=\"canvasSize().width\"\n\t\t\t\t\t[canvasHeight]=\"canvasSize().height\"\n\t\t\t\t\t[interactive]=\"interactive() && editTemplateMode()\"\n\t\t\t\t\t[marked]=\"interactive()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementIds()\"\n\t\t\t\t\t[editable]=\"editable() && editTemplateMode()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"allElements()\"\n\t\t\t\t\t[editTemplateMode]=\"editTemplateMode()\"\n\t\t\t\t\t[editingElementId]=\"editingId()\"\n\t\t\t\t\t(cellCommit)=\"cellCommit.emit($event)\"\n\t\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t@for (element of elements(); track element.id; let i = $index) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"element\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"visibleTemplateElements().length + i\"\n\t\t\t\t\t[obstacles]=\"connectorObstacles()\"\n\t\t\t\t\t[canvasWidth]=\"canvasSize().width\"\n\t\t\t\t\t[canvasHeight]=\"canvasSize().height\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementIds()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[editable]=\"editable()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"allElements()\"\n\t\t\t\t\t[editTemplateMode]=\"false\"\n\t\t\t\t\t[editingElementId]=\"editingId()\"\n\t\t\t\t\t(cellCommit)=\"cellCommit.emit($event)\"\n\t\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t<pptx-activex-controls-overlay\n\t\t\t\t[controls]=\"slide()?.activeXControls ?? []\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t/>\n\t\t\t@if (aiHighlights().length > 0 || aiActive()) {\n\t\t\t\t<pptx-ai-focus-highlight-overlay\n\t\t\t\t\t[highlights]=\"aiHighlights()\"\n\t\t\t\t\t[elements]=\"elements()\"\n\t\t\t\t\t[activeSlideIndex]=\"aiActiveSlideIndex()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t@if (aiChangeBatch(); as batch) {\n\t\t\t\t<pptx-ai-change-overlay [batch]=\"batch\" [activeSlideIndex]=\"aiActiveSlideIndex()\" />\n\t\t\t}\n\t\t\t@for (box of selectionBoxes(); track box.id) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-selection\"\n\t\t\t\t\t[style.left.px]=\"box.x\"\n\t\t\t\t\t[style.top.px]=\"box.y\"\n\t\t\t\t\t[style.width.px]=\"box.width\"\n\t\t\t\t\t[style.height.px]=\"box.height\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (h of handleBoxes(); track h.handle) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-handle\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.resize' | translate: { handle: h.handle }\"\n\t\t\t\t\t[style.left.px]=\"h.left\"\n\t\t\t\t\t[style.top.px]=\"h.top\"\n\t\t\t\t\t[style.width.px]=\"h.size\"\n\t\t\t\t\t[style.height.px]=\"h.size\"\n\t\t\t\t\t[style.cursor]=\"h.cursor\"\n\t\t\t\t\t(pointerdown)=\"onHandlePointerDown($event, h.handle)\"\n\t\t\t\t\t(keydown)=\"onResizeHandleKeydown($event, h.handle)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t@if (marqueeRect(); as mr) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-marquee\"\n\t\t\t\t\t[style.left.px]=\"mr.x\"\n\t\t\t\t\t[style.top.px]=\"mr.y\"\n\t\t\t\t\t[style.width.px]=\"mr.width\"\n\t\t\t\t\t[style.height.px]=\"mr.height\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (g of snapGuides(); track $index) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-snap-guide\"\n\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos : g.start\"\n\t\t\t\t\t[style.top.px]=\"g.axis === 'x' ? g.start : g.pos\"\n\t\t\t\t\t[style.width.px]=\"g.axis === 'x' ? 0 : g.end - g.start\"\n\t\t\t\t\t[style.height.px]=\"g.axis === 'x' ? g.end - g.start : 0\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@if (rotateHandle(); as rh) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-rotate-handle\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.rotate' | translate\"\n\t\t\t\t\t[style.left.px]=\"rh.left\"\n\t\t\t\t\t[style.top.px]=\"rh.top\"\n\t\t\t\t\t[style.width.px]=\"rh.size\"\n\t\t\t\t\t[style.height.px]=\"rh.size\"\n\t\t\t\t\t(pointerdown)=\"onRotatePointerDown($event)\"\n\t\t\t\t\t(keydown)=\"onRotateHandleKeydown($event)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<!--\n\t\t\t\tShape-adjustment affordances (amber diamonds), ONE per `a:avLst`\n\t\t\t\tguide. Existence, position and cursor all come from the SHARED\n\t\t\t\t`getShapeAdjustmentHandleDescriptors`, so they appear only for a\n\t\t\t\tgeometry with an adjustable parameter, sit where the other four\n\t\t\t\tbindings put them, and are absent for a shape locked with\n\t\t\t\t`noAdjustHandles`. Dragging one writes `shapeAdjustments`; it does\n\t\t\t\tNOT resize the element.\n\t\t\t-->\n\t\t\t@for (ah of adjustHandles(); track ah.key) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-adjust-handle\"\n\t\t\t\t\t[attr.data-pptx-adjust-key]=\"ah.key\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.adjust' | translate\"\n\t\t\t\t\t[style.left.px]=\"ah.left\"\n\t\t\t\t\t[style.top.px]=\"ah.top\"\n\t\t\t\t\t[style.width.px]=\"ah.size\"\n\t\t\t\t\t[style.height.px]=\"ah.size\"\n\t\t\t\t\t[style.cursor]=\"ah.cursor\"\n\t\t\t\t\t(pointerdown)=\"onAdjustPointerDown($event, ah)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<!--\n\t\t\t\tConnector endpoint authoring: drag an end onto a shape's connection\n\t\t\t\tpoint to bind it (`a:stCxn` / `a:endCxn`), or off one to detach.\n\t\t\t\tCandidate sites are revealed only while an end is in flight so they\n\t\t\t\tnever obscure the deck at rest.\n\t\t\t-->\n\t\t\t@for (site of connectorSiteCandidates(); track site.key) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-connection-site\"\n\t\t\t\t\t[class.is-snapped]=\"site.snapped\"\n\t\t\t\t\tdata-pptx-connection-site\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[style.left.px]=\"site.left\"\n\t\t\t\t\t[style.top.px]=\"site.top\"\n\t\t\t\t\t[style.width.px]=\"site.size\"\n\t\t\t\t\t[style.height.px]=\"site.size\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (ep of connectorEndpoints(); track ep.kind) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-connector-endpoint\"\n\t\t\t\t\t[class.is-attached]=\"ep.attached\"\n\t\t\t\t\t[attr.data-pptx-connector-endpoint]=\"ep.kind\"\n\t\t\t\t\t[attr.data-pptx-connector-attached]=\"ep.attached\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t(ep.kind === 'start'\n\t\t\t\t\t\t\t? 'pptx.canvas.connectorEndpointStart'\n\t\t\t\t\t\t\t: 'pptx.canvas.connectorEndpointEnd'\n\t\t\t\t\t\t) | translate\n\t\t\t\t\t\"\n\t\t\t\t\t[style.left.px]=\"ep.left\"\n\t\t\t\t\t[style.top.px]=\"ep.top\"\n\t\t\t\t\t[style.width.px]=\"ep.size\"\n\t\t\t\t\t[style.height.px]=\"ep.size\"\n\t\t\t\t\t(pointerdown)=\"onConnectorEndpointPointerDown($event, ep.kind)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t@if (editingBox(); as eb) {\n\t\t\t\t<textarea\n\t\t\t\t\t#textEditor\n\t\t\t\t\tdata-inline-editor\n\t\t\t\t\tclass=\"pptx-ng-text-editor\"\n\t\t\t\t\taria-label=\"Edit slide text\"\n\t\t\t\t\t[spellcheck]=\"spellCheck()\"\n\t\t\t\t\t[style.left.px]=\"eb.x\"\n\t\t\t\t\t[style.top.px]=\"eb.y\"\n\t\t\t\t\t[style.width.px]=\"eb.width\"\n\t\t\t\t\t[style.height.px]=\"eb.height\"\n\t\t\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t\t\t(input)=\"onTextInput($event, eb.id)\"\n\t\t\t\t\t(blur)=\"commitText($event, eb.id)\"\n\t\t\t\t\t(keydown)=\"onEditorKeydown($event)\"\n\t\t\t\t></textarea>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tView overlays: editor aids only, never on thumbnails/preview/presentation.\n\t\t\t\tAll are pointer-events:none so they never break selection/drag.\n\t\t\t\tNone carry data-pptx-element / aria-roledescription / data-pptx-viewport.\n\t\t\t-->\n\t\t\t@if (interactive() && showGrid()) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-overlay-grid\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t>\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t[attr.id]=\"gridPatternId\"\n\t\t\t\t\t\t\t[attr.width]=\"gridSpacingPx()\"\n\t\t\t\t\t\t\t[attr.height]=\"gridSpacingPx()\"\n\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t[attr.cx]=\"gridSpacingPx() / 2\"\n\t\t\t\t\t\t\t\t[attr.cy]=\"gridSpacingPx() / 2\"\n\t\t\t\t\t\t\t\tr=\"0.6\"\n\t\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.55)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</pattern>\n\t\t\t\t\t</defs>\n\t\t\t\t\t<rect\n\t\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t\t\t[attr.fill]=\"'url(#' + gridPatternId + ')'\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t@if (interactive() && showGuides()) {\n\t\t\t\t<!--\n\t\t\t\t\tCenter crosshair: one horizontal line and one vertical line\n\t\t\t\t\tthrough the midpoint of the slide. Static; draggable guides\n\t\t\t\t\tare a follow-up.\n\t\t\t\t-->\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-overlay-guides\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t>\n\t\t\t\t\t<!-- Horizontal center guide -->\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1=\"0\"\n\t\t\t\t\t\t[attr.y1]=\"canvasSize().height / 2\"\n\t\t\t\t\t\t[attr.x2]=\"canvasSize().width\"\n\t\t\t\t\t\t[attr.y2]=\"canvasSize().height / 2\"\n\t\t\t\t\t\tstroke=\"rgba(99,102,241,0.7)\"\n\t\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t\t\tstroke-dasharray=\"6 3\"\n\t\t\t\t\t/>\n\t\t\t\t\t<!-- Vertical center guide -->\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"canvasSize().width / 2\"\n\t\t\t\t\t\ty1=\"0\"\n\t\t\t\t\t\t[attr.x2]=\"canvasSize().width / 2\"\n\t\t\t\t\t\t[attr.y2]=\"canvasSize().height\"\n\t\t\t\t\t\tstroke=\"rgba(99,102,241,0.7)\"\n\t\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t\t\tstroke-dasharray=\"6 3\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tUser-created ruler guides.\n\t\t\t\tEach guide has a non-interactive line body and an interactive\n\t\t\t\tdrag handle. Double-click the handle to delete the guide.\n\n\t\t\t\tDeliberately OUTSIDE the showGuides() gate above (which owns the\n\t\t\t\tstatic centre crosshair): a guide the user just dragged off a ruler\n\t\t\t\tstrip must be visible immediately, as it is in Vue and Vanilla.\n\t\t\t\tWhile it lived under that gate, the drag-out gesture silently\n\t\t\t\tproduced an invisible guide unless View > Guides happened to be on.\n\t\t\t-->\n\t\t\t@if (interactive()) {\n\t\t\t\t@for (g of rulerGuidesSvc.rulerGuides(); track g.id) {\n\t\t\t\t\t<!-- Guide line body: pointer-events:none -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"pptx-ng-ruler-guide-line\"\n\t\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos : 0\"\n\t\t\t\t\t\t[style.top.px]=\"g.axis === 'y' ? g.pos : 0\"\n\t\t\t\t\t\t[style.width]=\"g.axis === 'x' ? '1px' : '100%'\"\n\t\t\t\t\t\t[style.height]=\"g.axis === 'y' ? '1px' : '100%'\"\n\t\t\t\t\t></div>\n\t\t\t\t\t<!-- Drag handle: pointer-events:auto -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"pptx-ng-ruler-guide-handle\"\n\t\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos - 4 : 0\"\n\t\t\t\t\t\t[style.top.px]=\"g.axis === 'y' ? g.pos - 4 : 0\"\n\t\t\t\t\t\t[style.width]=\"g.axis === 'x' ? '9px' : '100%'\"\n\t\t\t\t\t\t[style.height]=\"g.axis === 'y' ? '9px' : '100%'\"\n\t\t\t\t\t\t[style.cursor]=\"g.axis === 'x' ? 'col-resize' : 'row-resize'\"\n\t\t\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onGuidePointerDown($event, g.id, g.axis)\"\n\t\t\t\t\t\t(dblclick)=\"rulerGuidesSvc.onGuideDoubleClick($event, g.id)\"\n\t\t\t\t\t\t[title]=\"'pptx.canvas.guideTooltip' | translate\"\n\t\t\t\t\t></div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tLive ink stroke preview: shown while the user is drawing.\n\t\t\t\tpointer-events:none so it never intercepts element gestures.\n\t\t\t\tNo data-pptx-element / aria-roledescription / data-pptx-viewport.\n\n\t\t\t\tRenders `inkDrawing.liveStrokeView()`: the same plain-path /\n\t\t\t\tpressure-circle / tilt-nib decision `InkRendererComponent` makes for\n\t\t\t\ta committed stroke, so a calligraphic lean or pressure-variable\n\t\t\t\twidth shows up while the pointer is still down, not only after\n\t\t\t\trelease.\n\t\t\t-->\n\t\t\t@if (inkDrawing.active() && inkDrawing.liveStrokeView() && drawTool() !== 'select') {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-ink-preview\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none; z-index: 70\"\n\t\t\t\t>\n\t\t\t\t\t@if (inkDrawing.liveStrokeView()?.nibMarks; as nibMarks) {\n\t\t\t\t\t\t<g [attr.opacity]=\"inkDrawing.liveStrokeView()?.opacity\">\n\t\t\t\t\t\t\t@for (m of nibMarks; track $index) {\n\t\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"m.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"m.cy\"\n\t\t\t\t\t\t\t\t\t[attr.rx]=\"m.rPerp\"\n\t\t\t\t\t\t\t\t\t[attr.ry]=\"m.rTilt\"\n\t\t\t\t\t\t\t\t\t[attr.transform]=\"'rotate(' + m.rotationDeg + ' ' + m.cx + ' ' + m.cy + ')'\"\n\t\t\t\t\t\t\t\t\t[attr.fill]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t} @else if (inkDrawing.liveStrokeView()?.circles; as circles) {\n\t\t\t\t\t\t<g [attr.opacity]=\"inkDrawing.liveStrokeView()?.opacity\">\n\t\t\t\t\t\t\t@for (c of circles; track $index) {\n\t\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"c.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"c.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"c.r\"\n\t\t\t\t\t\t\t\t\t[attr.fill]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"inkDrawing.liveStrokeView()?.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"inkDrawing.liveStrokeView()?.width\"\n\t\t\t\t\t\t\t[attr.stroke-opacity]=\"inkDrawing.liveStrokeView()?.opacity\"\n\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tProjected overlays (collaboration cursors + remote selections).\n\t\t\t\tThey live INSIDE the scaled stage so the stage's CSS\n\t\t\t\ttransform:scale() applies the on-screen scale exactly once and\n\t\t\t\tthey can be authored in raw, unscaled slide coordinates, exactly\n\t\t\t\tlike the React/Vue overlays.\n\t\t\t-->\n\t\t\t<ng-content />\n\t\t</div>\n\n\t\t<!--\n\t\t\tRuler strips: siblings to the scaled stage inside the wrapper div,\n\t\t\tabsolutely positioned at top:0/left:0 within the wrapper's padding area.\n\t\t\tThe wrapper's padding (RULER_THICKNESS px top+left) reserves space for\n\t\t\tthese strips so the stage content starts below/right of them.\n\t\t\tpointer-events:none so they never intercept element gestures.\n\t\t-->\n\t\t@if (interactive() && showRulers()) {\n\t\t\t<!-- Corner square at the intersection of the two ruler strips -->\n\t\t\t<div class=\"pptx-ng-ruler-corner\" aria-hidden=\"true\"></div>\n\n\t\t\t<!--\n\t\t\t\tHorizontal ruler: spans the top padding row of the wrapper.\n\t\t\t\tA guide is dropped on pointer-UP (not down), resolved by the shared\n\t\t\t\trulerDragToGuidePosition, so a stray click on the strip cannot\n\t\t\t\tdrop a guide the user never dragged out - the rule React, Vue,\n\t\t\t\tSvelte and Vanilla all follow.\n\t\t\t-->\n\t\t\t<svg\n\t\t\t\tclass=\"pptx-ng-ruler-h\"\n\t\t\t\tdata-pptx-ruler=\"h\"\n\t\t\t\trole=\"presentation\"\n\t\t\t\t[attr.width]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t[style.cursor]=\"editable() ? 'row-resize' : null\"\n\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onRulerPointerDown('h', $event)\"\n\t\t\t\t(pointerup)=\"rulerGuidesSvc.onRulerPointerUp('h', $event)\"\n\t\t\t>\n\t\t\t\t<rect\n\t\t\t\t\t[attr.width]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t\tfill=\"#1e293b\"\n\t\t\t\t/>\n\t\t\t\t@if (hRulerHighlight(); as highlight) {\n\t\t\t\t\t<rect\n\t\t\t\t\t\t[attr.x]=\"highlight.start\"\n\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t[attr.width]=\"highlight.span\"\n\t\t\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t\t\tfill=\"rgba(96,165,250,0.25)\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t<line\n\t\t\t\t\tx1=\"0\"\n\t\t\t\t\t[attr.y1]=\"rulerThickness - 0.5\"\n\t\t\t\t\t[attr.x2]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t\t[attr.y2]=\"rulerThickness - 0.5\"\n\t\t\t\t\tstroke=\"rgba(255,255,255,0.15)\"\n\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t/>\n\t\t\t\t@for (tick of hRulerTicks(); track $index) {\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"tick.position\"\n\t\t\t\t\t\t[attr.y1]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.x2]=\"tick.position\"\n\t\t\t\t\t\t[attr.y2]=\"rulerThickness - rulerThickness * (tick.isMajor ? 0.6 : 0.3)\"\n\t\t\t\t\t\tstroke=\"rgba(156,163,175,0.7)\"\n\t\t\t\t\t\t[attr.stroke-width]=\"tick.isMajor ? 1 : 0.5\"\n\t\t\t\t\t/>\n\t\t\t\t\t@if (tick.label) {\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t[attr.x]=\"tick.position + 2\"\n\t\t\t\t\t\t\t[attr.y]=\"rulerFontSize + 1\"\n\t\t\t\t\t\t\t[attr.font-size]=\"rulerFontSize\"\n\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.9)\"\n\t\t\t\t\t\t\tstyle=\"font-family: system-ui, sans-serif\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ tick.label }}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\n\t\t\t<!-- Vertical ruler: spans the left padding column of the wrapper -->\n\t\t\t<svg\n\t\t\t\tclass=\"pptx-ng-ruler-v\"\n\t\t\t\tdata-pptx-ruler=\"v\"\n\t\t\t\trole=\"presentation\"\n\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t[attr.height]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t[style.cursor]=\"editable() ? 'col-resize' : null\"\n\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onRulerPointerDown('v', $event)\"\n\t\t\t\t(pointerup)=\"rulerGuidesSvc.onRulerPointerUp('v', $event)\"\n\t\t\t>\n\t\t\t\t<rect\n\t\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t\tfill=\"#1e293b\"\n\t\t\t\t/>\n\t\t\t\t@if (vRulerHighlight(); as highlight) {\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t[attr.y]=\"highlight.start\"\n\t\t\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.height]=\"highlight.span\"\n\t\t\t\t\t\tfill=\"rgba(96,165,250,0.25)\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t<line\n\t\t\t\t\t[attr.x1]=\"rulerThickness - 0.5\"\n\t\t\t\t\ty1=\"0\"\n\t\t\t\t\t[attr.x2]=\"rulerThickness - 0.5\"\n\t\t\t\t\t[attr.y2]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t\tstroke=\"rgba(255,255,255,0.15)\"\n\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t/>\n\t\t\t\t@for (tick of vRulerTicks(); track $index) {\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.y1]=\"tick.position\"\n\t\t\t\t\t\t[attr.x2]=\"rulerThickness - rulerThickness * (tick.isMajor ? 0.6 : 0.3)\"\n\t\t\t\t\t\t[attr.y2]=\"tick.position\"\n\t\t\t\t\t\tstroke=\"rgba(156,163,175,0.7)\"\n\t\t\t\t\t\t[attr.stroke-width]=\"tick.isMajor ? 1 : 0.5\"\n\t\t\t\t\t/>\n\t\t\t\t\t@if (tick.label) {\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx=\"2\"\n\t\t\t\t\t\t\t[attr.y]=\"tick.position + rulerFontSize + 2\"\n\t\t\t\t\t\t\t[attr.font-size]=\"rulerFontSize\"\n\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.9)\"\n\t\t\t\t\t\t\tstyle=\"font-family: system-ui, sans-serif\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ tick.label }}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t}\n\t</div>\n</div>\n", styles: [".pptx-ng-canvas-stage.is-editable{touch-action:none}\n"] }]
125021
- }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], rulerUnit: [{ type: i0.Input, args: [{ isSignal: true, alias: "rulerUnit", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], gridSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridSpacing", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], transparentBackground: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparentBackground", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], exposeElementIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementIds", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], transformEnd: [{ type: i0.Output, args: ["transformEnd"] }], adjustUpdate: [{ type: i0.Output, args: ["adjustUpdate"] }], connectorEndpointUpdate: [{ type: i0.Output, args: ["connectorEndpointUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textInput: [{ type: i0.Output, args: ["textInput"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
125366
+ }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], fitPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitPadding", required: false }] }], maxFitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFitScale", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], rulerUnit: [{ type: i0.Input, args: [{ isSignal: true, alias: "rulerUnit", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], gridSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridSpacing", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], transparentBackground: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparentBackground", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], exposeElementIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementIds", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], transformEnd: [{ type: i0.Output, args: ["transformEnd"] }], adjustUpdate: [{ type: i0.Output, args: ["adjustUpdate"] }], connectorEndpointUpdate: [{ type: i0.Output, args: ["connectorEndpointUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textInput: [{ type: i0.Output, args: ["textInput"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
125022
125367
  type: HostListener,
125023
125368
  args: ['document:pointermove', ['$event']]
125024
125369
  }], onPointerUp: [{
@@ -125184,7 +125529,7 @@ class MasterViewCanvasComponent {
125184
125529
  <p class="empty">No master is available.</p>
125185
125530
  }
125186
125531
  </main>
125187
- `, isInline: true, styles: [":host{display:flex;min-width:0;min-height:0;flex:1}.master-canvas{display:flex;min-width:0;min-height:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;min-height:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
125532
+ `, isInline: true, styles: [":host{display:flex;min-width:0;min-height:0;flex:1}.master-canvas{display:flex;min-width:0;min-height:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;min-height:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
125188
125533
  }
125189
125534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MasterViewCanvasComponent, decorators: [{
125190
125535
  type: Component,
@@ -126441,7 +126786,7 @@ class MobilePresenterViewComponent {
126441
126786
  return { ...slide, elements: [...template, ...slide.elements] };
126442
126787
  }
126443
126788
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobilePresenterViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
126444
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MobilePresenterViewComponent, isStandalone: true, selector: "pptx-mobile-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<!-- Header: elapsed + counter + exit -->\n\t<div class=\"pptx-ng-mpresenter-header\">\n\t\t<div>\n\t\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t<div class=\"pptx-ng-mpresenter-elapsed\">{{ elapsedLabel() }}</div>\n\t\t</div>\n\t\t<span class=\"pptx-ng-mpresenter-counter\">{{ counterLabel() }}</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-exit\"\n\t\t\t(click)=\"exit.emit()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t>\n\t\t\t&#x2715;\n\t\t</button>\n\t</div>\n\n\t<!-- Current slide (large) -->\n\t<div class=\"pptx-ng-mpresenter-main\">\n\t\t<div class=\"pptx-ng-mpresenter-main-stage\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"1\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n\n\t<!-- Next thumbnail -->\n\t<div class=\"pptx-ng-mpresenter-next\">\n\t\t<span class=\"pptx-ng-mpresenter-label\">{{\n\t\t\t'pptx.presenter.nextSlidePreview' | translate\n\t\t}}</span>\n\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t<div class=\"pptx-ng-mpresenter-thumb\" [ngStyle]=\"thumbStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<div class=\"pptx-ng-mpresenter-next-empty\">\n\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<!-- Speaker notes (scrollable) -->\n\t<div class=\"pptx-ng-mpresenter-notes\">\n\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.speakerNotes' | translate }}</div>\n\t\t<div class=\"pptx-ng-mpresenter-notes-body\">\n\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t<br />\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t{{ notes().plainText }}\n\t\t\t} @else {\n\t\t\t\t<span class=\"pptx-ng-mpresenter-notes-empty\">{{\n\t\t\t\t\t'pptx.presenter.noNotes' | translate\n\t\t\t\t}}</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- Prev / Next controls -->\n\t<div class=\"pptx-ng-mpresenter-ctl\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t>\n\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t>\n\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t</button>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-mpresenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126789
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MobilePresenterViewComponent, isStandalone: true, selector: "pptx-mobile-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<!-- Header: elapsed + counter + exit -->\n\t<div class=\"pptx-ng-mpresenter-header\">\n\t\t<div>\n\t\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t<div class=\"pptx-ng-mpresenter-elapsed\">{{ elapsedLabel() }}</div>\n\t\t</div>\n\t\t<span class=\"pptx-ng-mpresenter-counter\">{{ counterLabel() }}</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-exit\"\n\t\t\t(click)=\"exit.emit()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t>\n\t\t\t&#x2715;\n\t\t</button>\n\t</div>\n\n\t<!-- Current slide (large) -->\n\t<div class=\"pptx-ng-mpresenter-main\">\n\t\t<div class=\"pptx-ng-mpresenter-main-stage\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"1\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n\n\t<!-- Next thumbnail -->\n\t<div class=\"pptx-ng-mpresenter-next\">\n\t\t<span class=\"pptx-ng-mpresenter-label\">{{\n\t\t\t'pptx.presenter.nextSlidePreview' | translate\n\t\t}}</span>\n\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t<div class=\"pptx-ng-mpresenter-thumb\" [ngStyle]=\"thumbStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<div class=\"pptx-ng-mpresenter-next-empty\">\n\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<!-- Speaker notes (scrollable) -->\n\t<div class=\"pptx-ng-mpresenter-notes\">\n\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.speakerNotes' | translate }}</div>\n\t\t<div class=\"pptx-ng-mpresenter-notes-body\">\n\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t<br />\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t{{ notes().plainText }}\n\t\t\t} @else {\n\t\t\t\t<span class=\"pptx-ng-mpresenter-notes-empty\">{{\n\t\t\t\t\t'pptx.presenter.noNotes' | translate\n\t\t\t\t}}</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- Prev / Next controls -->\n\t<div class=\"pptx-ng-mpresenter-ctl\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t>\n\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t>\n\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t</button>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-mpresenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126445
126790
  }
126446
126791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobilePresenterViewComponent, decorators: [{
126447
126792
  type: Component,
@@ -126617,7 +126962,7 @@ class MobileSlidesSheetComponent {
126617
126962
  }
126618
126963
  </div>
126619
126964
  </pptx-mobile-sheet>
126620
- `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { 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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126965
+ `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126621
126966
  }
126622
126967
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobileSlidesSheetComponent, decorators: [{
126623
126968
  type: Component,
@@ -131668,6 +132013,7 @@ class ViewerKeyboardService {
131668
132013
  }
131669
132014
  const { action, dx, dy } = mapEditorKey(event, {
131670
132015
  canEdit: host.canEdit(),
132016
+ canPaste: this.editor.hasClipboard(),
131671
132017
  isPresenting: host.presenting(),
131672
132018
  hasSelection: this.editor.hasSelection(),
131673
132019
  isDrawing: host.isDrawing?.() ?? false,
@@ -134592,7 +134938,7 @@ class FragmentedTransitionLayerComponent {
134592
134938
  </div>
134593
134939
  }
134594
134940
  </div>
134595
- `, isInline: true, styles: [":host{display:block}.pptx-ng-transition-layer{position:absolute;inset:0}.pptx-ng-transition-fragment{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134941
+ `, isInline: true, styles: [":host{display:block}.pptx-ng-transition-layer{position:absolute;inset:0}.pptx-ng-transition-fragment{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;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", "fitPadding", "maxFitScale", "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134596
134942
  }
134597
134943
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: FragmentedTransitionLayerComponent, decorators: [{
134598
134944
  type: Component,
@@ -134724,7 +135070,7 @@ class MorphExtraLayersComponent {
134724
135070
  </div>
134725
135071
  </div>
134726
135072
  }
134727
- `, isInline: true, styles: [".pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135073
+ `, isInline: true, styles: [".pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134728
135074
  }
134729
135075
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MorphExtraLayersComponent, decorators: [{
134730
135076
  type: Component,
@@ -135285,7 +135631,7 @@ class PresentationTransitionOverlayComponent {
135285
135631
  });
135286
135632
  }
135287
135633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationTransitionOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
135288
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, incomingSlide: { classPropertyName: "incomingSlide", publicName: "incomingSlide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: "<!-- The seven multi-fragment cinematic transitions (vortex, honeycomb,\n glitter, shred, fracture, curtains, airplane) replace whichever\n layer(s) 'getFragmentedTransitionDescriptor' names with N clipped\n copies of the slide instead of one animated block. Morph never sets\n 'fragmented' (it is its own transition type), so the two never race. -->\n@if (fragmentedIncoming(); as fragIncoming) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragIncoming\"\n\t\t[slide]=\"incomingFragmentSlide()!\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"incoming\"\n\t\t[zIndex]=\"fragmentedIncomingZIndex()\"\n\t/>\n} @else if (incomingLayerSlide(); as incoming) {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"incoming\"\n\t\t[ngStyle]=\"incomingLayerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"incoming\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n@if (fragmentedOutgoing(); as fragOutgoing) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragOutgoing\"\n\t\t[slide]=\"layerSlide()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"outgoing\"\n\t\t[zIndex]=\"fragmentedOutgoingZIndex()\"\n\t/>\n} @else {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"outgoing\"\n\t\t[attr.data-pptx-morph-outgoing]=\"morphPlan() ? 'true' : null\"\n\t\t[ngStyle]=\"layerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"layerSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t\t[transparentBackground]=\"isMorph()\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n<!-- The two morph-only extra layers (arriving-above-departing \"lifted\"\n shapes, and same-pair crossfade groups) - see\n `MorphExtraLayersComponent`. -->\n<pptx-morph-extra-layers\n\t[liftedSlide]=\"liftedSlide()\"\n\t[crossfadeGroups]=\"crossfadeGroups()\"\n\t[canvasSize]=\"canvasSize()\"\n\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t[zoom]=\"zoom()\"\n\t[slideBoxStyle]=\"slideBoxStyle()\"\n/>\n", styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\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: FragmentedTransitionLayerComponent, selector: "pptx-fragmented-transition-layer", inputs: ["layer", "slide", "canvasSize", "mediaDataUrls", "zoom", "layerName", "zIndex"] }, { kind: "component", type: MorphExtraLayersComponent, selector: "pptx-morph-extra-layers", inputs: ["liftedSlide", "crossfadeGroups", "canvasSize", "mediaDataUrls", "zoom", "slideBoxStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, incomingSlide: { classPropertyName: "incomingSlide", publicName: "incomingSlide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: "<!-- The seven multi-fragment cinematic transitions (vortex, honeycomb,\n glitter, shred, fracture, curtains, airplane) replace whichever\n layer(s) 'getFragmentedTransitionDescriptor' names with N clipped\n copies of the slide instead of one animated block. Morph never sets\n 'fragmented' (it is its own transition type), so the two never race. -->\n@if (fragmentedIncoming(); as fragIncoming) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragIncoming\"\n\t\t[slide]=\"incomingFragmentSlide()!\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"incoming\"\n\t\t[zIndex]=\"fragmentedIncomingZIndex()\"\n\t/>\n} @else if (incomingLayerSlide(); as incoming) {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"incoming\"\n\t\t[ngStyle]=\"incomingLayerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"incoming\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n@if (fragmentedOutgoing(); as fragOutgoing) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragOutgoing\"\n\t\t[slide]=\"layerSlide()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"outgoing\"\n\t\t[zIndex]=\"fragmentedOutgoingZIndex()\"\n\t/>\n} @else {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"outgoing\"\n\t\t[attr.data-pptx-morph-outgoing]=\"morphPlan() ? 'true' : null\"\n\t\t[ngStyle]=\"layerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"layerSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t\t[transparentBackground]=\"isMorph()\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n<!-- The two morph-only extra layers (arriving-above-departing \"lifted\"\n shapes, and same-pair crossfade groups) - see\n `MorphExtraLayersComponent`. -->\n<pptx-morph-extra-layers\n\t[liftedSlide]=\"liftedSlide()\"\n\t[crossfadeGroups]=\"crossfadeGroups()\"\n\t[canvasSize]=\"canvasSize()\"\n\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t[zoom]=\"zoom()\"\n\t[slideBoxStyle]=\"slideBoxStyle()\"\n/>\n", styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: FragmentedTransitionLayerComponent, selector: "pptx-fragmented-transition-layer", inputs: ["layer", "slide", "canvasSize", "mediaDataUrls", "zoom", "layerName", "zIndex"] }, { kind: "component", type: MorphExtraLayersComponent, selector: "pptx-morph-extra-layers", inputs: ["liftedSlide", "crossfadeGroups", "canvasSize", "mediaDataUrls", "zoom", "slideBoxStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135289
135635
  }
135290
135636
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationTransitionOverlayComponent, decorators: [{
135291
135637
  type: Component,
@@ -135405,7 +135751,7 @@ class PresenterSlideNavigatorComponent {
135405
135751
  }
135406
135752
  </div>
135407
135753
  </div>
135408
- `, isInline: true, dependencies: [{ 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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135754
+ `, isInline: true, dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135409
135755
  }
135410
135756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterSlideNavigatorComponent, decorators: [{
135411
135757
  type: Component,
@@ -136303,7 +136649,7 @@ class PresentationOverlayComponent {
136303
136649
  this.closed.emit();
136304
136650
  }
136305
136651
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
136306
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", 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 }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, loopContinuously: { classPropertyName: "loopContinuously", publicName: "loopContinuously", 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 }, pixelateMosaicAnimation: { classPropertyName: "pixelateMosaicAnimation", publicName: "pixelateMosaicAnimation", 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", customShowRequest: "customShowRequest", endOfShowChange: "endOfShowChange" }, 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\n\t<!-- `ppaction://program` (\"Run program\") notices: see run-program-notices.component.ts. -->\n\t<pptx-run-program-notices\n\t\t[notices]=\"runProgramNotices.notices()\"\n\t\t(dismiss)=\"runProgramNotices.dismiss($event)\"\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: RunProgramNoticesComponent, selector: "pptx-run-program-notices", inputs: ["notices"], outputs: ["dismiss"] }, { 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 }); }
136652
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", 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 }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, loopContinuously: { classPropertyName: "loopContinuously", publicName: "loopContinuously", 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 }, pixelateMosaicAnimation: { classPropertyName: "pixelateMosaicAnimation", publicName: "pixelateMosaicAnimation", 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", customShowRequest: "customShowRequest", endOfShowChange: "endOfShowChange" }, 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\n\t<!-- `ppaction://program` (\"Run program\") notices: see run-program-notices.component.ts. -->\n\t<pptx-run-program-notices\n\t\t[notices]=\"runProgramNotices.notices()\"\n\t\t(dismiss)=\"runProgramNotices.dismiss($event)\"\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", "fitPadding", "maxFitScale", "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: RunProgramNoticesComponent, selector: "pptx-run-program-notices", inputs: ["notices"], outputs: ["dismiss"] }, { 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 }); }
136307
136653
  }
136308
136654
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
136309
136655
  type: Component,
@@ -137008,7 +137354,7 @@ class PresenterViewComponent {
137008
137354
  return { ...slide, elements: [...template, ...slide.elements] };
137009
137355
  }
137010
137356
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
137011
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresenterViewComponent, isStandalone: true, selector: "pptx-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, isAudienceWindowOpen: { classPropertyName: "isAudienceWindowOpen", publicName: "isAudienceWindowOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit", openAudienceWindow: "openAudienceWindow", closeAudienceWindow: "closeAudienceWindow", navigateToSlide: "navigateToSlide" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<pptx-presenter-controls\n\t\t[snapshot]=\"presenterWindow.snapshot()\"\n\t\t[audienceOpen]=\"isAudienceWindowOpen()\"\n\t\t[slides]=\"slides()\"\n\t\t[current]=\"currentSlideIndex()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[templateElements]=\"templateElements()\"\n\t\t(patch)=\"presenterWindow.updateSnapshot($event)\"\n\t\t(navigate)=\"navigateToSlide.emit($event)\"\n\t\t(audience)=\"onToggleAudienceWindow()\"\n\t\t(swapDisplays)=\"onSwapDisplays()\"\n\t\t(end)=\"exit.emit()\"\n\t/>\n\t<div class=\"pptx-ng-presenter-body\">\n\t\t<!-- Current slide (\u224870%) -->\n\t\t<div\n\t\t\tclass=\"pptx-ng-presenter-current\"\n\t\t\t[class.pptx-ng-presenter-current--advances]=\"paneAdvancesOnClick()\"\n\t\t\trole=\"presentation\"\n\t\t\tdata-pptx-presenter-slide\n\t\t\t(click)=\"onSlidePaneClick()\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-presenter-preview-stage\" [ngStyle]=\"previewStageStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div class=\"pptx-ng-presenter-slide-badge\">{{ slideBadge() }}</div>\n\t\t</div>\n\n\t\t<!-- Controls (\u224830%) -->\n\t\t<div class=\"pptx-ng-presenter-side\">\n\t\t\t<!-- Header: clock + elapsed + window/exit -->\n\t\t\t<div class=\"pptx-ng-presenter-header\">\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.currentTime' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock\">{{ clockLabel() }}</div>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock pptx-ng-presenter-elapsed\">\n\t\t\t\t\t\t{{ elapsedLabel() }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"display: flex; align-items: center; gap: 0.25rem\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"onToggleAudienceWindow()\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t[title]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ isAudienceWindowOpen() ? '\u25A3' : '\u25A1' }}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"exit.emit()\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&#x2715;\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Navigation -->\n\t\t\t<div class=\"pptx-ng-presenter-nav\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t>\n\t\t\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t\t\t</button>\n\t\t\t\t<span class=\"pptx-ng-presenter-counter\">{{ counterLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<!-- Next slide preview -->\n\t\t\t<div class=\"pptx-ng-presenter-next\" data-pptx-presenter-next-preview>\n\t\t\t\t<div class=\"pptx-ng-presenter-label\" style=\"margin-bottom: 0.5rem\">\n\t\t\t\t\t{{ 'pptx.presenter.nextSlidePreview' | translate }}\n\t\t\t\t</div>\n\t\t\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t/>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"pptx-ng-presenter-next-empty\">\n\t\t\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<!-- Speaker notes -->\n\t\t\t<div class=\"pptx-ng-presenter-notes\" data-pptx-presenter-notes>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-head\">\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.speakerNotes' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-notes-size\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"decreaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() <= NOTES_FONT_SIZE_MIN\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-decrease\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2212;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-size-value\">{{ notesFontSize() }}px</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"increaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() >= NOTES_FONT_SIZE_MAX\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-increase\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2b;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-body\" [ngStyle]=\"notesBodyStyle()\">\n\t\t\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t\t\t{{ notes().plainText }}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-empty\">\n\t\t\t\t\t\t\t{{ 'pptx.presenter.noNotes' | translate }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Timer progress bar -->\n\t<div\n\t\tclass=\"pptx-ng-presenter-progress\"\n\t\trole=\"progressbar\"\n\t\t[attr.aria-valuenow]=\"progressValue()\"\n\t\taria-valuemin=\"0\"\n\t\taria-valuemax=\"100\"\n\t\t[attr.aria-label]=\"'pptx.presenter.timerProgress' | translate\"\n\t>\n\t\t<div class=\"pptx-ng-presenter-progress-fill\" [style.width.%]=\"timerPercent()\"></div>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-presenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0;overflow:hidden}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0;transition:transform .2s ease}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\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: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["patch", "navigate", "audience", "swapDisplays", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
137357
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresenterViewComponent, isStandalone: true, selector: "pptx-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, isAudienceWindowOpen: { classPropertyName: "isAudienceWindowOpen", publicName: "isAudienceWindowOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit", openAudienceWindow: "openAudienceWindow", closeAudienceWindow: "closeAudienceWindow", navigateToSlide: "navigateToSlide" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<pptx-presenter-controls\n\t\t[snapshot]=\"presenterWindow.snapshot()\"\n\t\t[audienceOpen]=\"isAudienceWindowOpen()\"\n\t\t[slides]=\"slides()\"\n\t\t[current]=\"currentSlideIndex()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[templateElements]=\"templateElements()\"\n\t\t(patch)=\"presenterWindow.updateSnapshot($event)\"\n\t\t(navigate)=\"navigateToSlide.emit($event)\"\n\t\t(audience)=\"onToggleAudienceWindow()\"\n\t\t(swapDisplays)=\"onSwapDisplays()\"\n\t\t(end)=\"exit.emit()\"\n\t/>\n\t<div class=\"pptx-ng-presenter-body\">\n\t\t<!-- Current slide (\u224870%) -->\n\t\t<div\n\t\t\tclass=\"pptx-ng-presenter-current\"\n\t\t\t[class.pptx-ng-presenter-current--advances]=\"paneAdvancesOnClick()\"\n\t\t\trole=\"presentation\"\n\t\t\tdata-pptx-presenter-slide\n\t\t\t(click)=\"onSlidePaneClick()\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-presenter-preview-stage\" [ngStyle]=\"previewStageStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div class=\"pptx-ng-presenter-slide-badge\">{{ slideBadge() }}</div>\n\t\t</div>\n\n\t\t<!-- Controls (\u224830%) -->\n\t\t<div class=\"pptx-ng-presenter-side\">\n\t\t\t<!-- Header: clock + elapsed + window/exit -->\n\t\t\t<div class=\"pptx-ng-presenter-header\">\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.currentTime' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock\">{{ clockLabel() }}</div>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock pptx-ng-presenter-elapsed\">\n\t\t\t\t\t\t{{ elapsedLabel() }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"display: flex; align-items: center; gap: 0.25rem\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"onToggleAudienceWindow()\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t[title]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ isAudienceWindowOpen() ? '\u25A3' : '\u25A1' }}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"exit.emit()\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&#x2715;\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Navigation -->\n\t\t\t<div class=\"pptx-ng-presenter-nav\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t>\n\t\t\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t\t\t</button>\n\t\t\t\t<span class=\"pptx-ng-presenter-counter\">{{ counterLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<!-- Next slide preview -->\n\t\t\t<div class=\"pptx-ng-presenter-next\" data-pptx-presenter-next-preview>\n\t\t\t\t<div class=\"pptx-ng-presenter-label\" style=\"margin-bottom: 0.5rem\">\n\t\t\t\t\t{{ 'pptx.presenter.nextSlidePreview' | translate }}\n\t\t\t\t</div>\n\t\t\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t/>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"pptx-ng-presenter-next-empty\">\n\t\t\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<!-- Speaker notes -->\n\t\t\t<div class=\"pptx-ng-presenter-notes\" data-pptx-presenter-notes>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-head\">\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.speakerNotes' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-notes-size\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"decreaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() <= NOTES_FONT_SIZE_MIN\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-decrease\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2212;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-size-value\">{{ notesFontSize() }}px</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"increaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() >= NOTES_FONT_SIZE_MAX\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-increase\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2b;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-body\" [ngStyle]=\"notesBodyStyle()\">\n\t\t\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t\t\t{{ notes().plainText }}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-empty\">\n\t\t\t\t\t\t\t{{ 'pptx.presenter.noNotes' | translate }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Timer progress bar -->\n\t<div\n\t\tclass=\"pptx-ng-presenter-progress\"\n\t\trole=\"progressbar\"\n\t\t[attr.aria-valuenow]=\"progressValue()\"\n\t\taria-valuemin=\"0\"\n\t\taria-valuemax=\"100\"\n\t\t[attr.aria-label]=\"'pptx.presenter.timerProgress' | translate\"\n\t>\n\t\t<div class=\"pptx-ng-presenter-progress-fill\" [style.width.%]=\"timerPercent()\"></div>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-presenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0;overflow:hidden}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0;transition:transform .2s ease}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["patch", "navigate", "audience", "swapDisplays", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
137012
137358
  }
137013
137359
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterViewComponent, decorators: [{
137014
137360
  type: Component,
@@ -138417,7 +138763,7 @@ class ReadingViewOverlayComponent {
138417
138763
  </div>
138418
138764
  </div>
138419
138765
  }
138420
- `, isInline: true, styles: [".pptx-ng-reading-root{position:fixed;inset:0;z-index:1300;display:flex;flex-direction:column;background:#171717}.pptx-ng-reading-viewport{display:flex;flex:1 1 0%;min-height:0;align-items:center;justify-content:center}.pptx-ng-reading-stage{position:relative;overflow:hidden}.pptx-ng-reading-stage ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-reading-nav{display:flex;flex-shrink:0;align-items:center;justify-content:center;gap:.75rem;padding:.5rem 1rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-reading-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:.25rem;background:transparent;color:#fffc;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-reading-btn:hover:not(:disabled){background:#ffffff26;color:#fff}.pptx-ng-reading-btn:disabled{cursor:default;opacity:.3}.pptx-ng-reading-counter{min-width:4rem;text-align:center;font-size:.75rem;font-variant-numeric:tabular-nums;color:#ffffffb3}\n"], dependencies: [{ 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: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
138766
+ `, isInline: true, styles: [".pptx-ng-reading-root{position:fixed;inset:0;z-index:1300;display:flex;flex-direction:column;background:#171717}.pptx-ng-reading-viewport{display:flex;flex:1 1 0%;min-height:0;align-items:center;justify-content:center}.pptx-ng-reading-stage{position:relative;overflow:hidden}.pptx-ng-reading-stage ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-reading-nav{display:flex;flex-shrink:0;align-items:center;justify-content:center;gap:.75rem;padding:.5rem 1rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-reading-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:.25rem;background:transparent;color:#fffc;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-reading-btn:hover:not(:disabled){background:#ffffff26;color:#fff}.pptx-ng-reading-btn:disabled{cursor:default;opacity:.3}.pptx-ng-reading-counter{min-width:4rem;text-align:center;font-size:.75rem;font-variant-numeric:tabular-nums;color:#ffffffb3}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
138421
138767
  }
138422
138768
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ReadingViewOverlayComponent, decorators: [{
138423
138769
  type: Component,
@@ -139071,9 +139417,30 @@ function patchTextStyle(editor, slideIndex, el, patch) {
139071
139417
  if (!el || !hasTextProperties(el)) {
139072
139418
  return;
139073
139419
  }
139074
- editor.updateElement(slideIndex, el.id, {
139075
- textStyle: { ...el.textStyle, ...patch },
139076
- });
139420
+ const { listType, ...stylePatch } = patch;
139421
+ if (listType !== undefined) {
139422
+ const liveText = currentInlineEditorText();
139423
+ const base = liveText === undefined
139424
+ ? el
139425
+ : {
139426
+ ...el,
139427
+ text: liveText,
139428
+ textSegments: el.textSegments
139429
+ ? remapTextToSegments(liveText, el.textSegments, el.textStyle)
139430
+ : undefined,
139431
+ };
139432
+ const listed = { ...base, ...setElementBullets(base, listType) };
139433
+ if (!hasTextProperties(listed)) {
139434
+ return;
139435
+ }
139436
+ editor.updateElement(slideIndex, el.id, {
139437
+ ...(liveText !== undefined ? { text: liveText } : {}),
139438
+ textSegments: listed.textSegments,
139439
+ ...textStylePatch(listed, stylePatch),
139440
+ });
139441
+ return;
139442
+ }
139443
+ editor.updateElement(slideIndex, el.id, textStylePatch(el, patch));
139077
139444
  }
139078
139445
  /**
139079
139446
  * Rewrite the selection's text characters (ribbon Aa "Change Case" dropdown).
@@ -143678,7 +144045,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
143678
144045
  }], 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 }] }] } });
143679
144046
 
143680
144047
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
143681
- const PPTX_ANGULAR_VIEWER_VERSION = "3.16.6";
144048
+ const PPTX_ANGULAR_VIEWER_VERSION = "3.17.0";
143682
144049
 
143683
144050
  /**
143684
144051
  * account-page.component.ts: File > Account content.
@@ -144983,12 +145350,19 @@ class RibbonParagraphControlsComponent {
144983
145350
  ...(ngDevMode ? [{ debugName: "slideIndex" }] : /* istanbul ignore next */ []));
144984
145351
  this.selectedElement = input(null, /* @ts-ignore */
144985
145352
  ...(ngDevMode ? [{ debugName: "selectedElement" }] : /* istanbul ignore next */ []));
145353
+ this.canEdit = input(false, /* @ts-ignore */
145354
+ ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
144986
145355
  this.lineSpacingOptions = LINE_SPACING_OPTIONS;
144987
145356
  this.textDirectionOptions = TEXT_DIRECTION_OPTIONS;
144988
145357
  this.columnOptions = COLUMN_OPTIONS;
144989
145358
  /** Current text style of the selection (for active-state highlighting). */
144990
145359
  this.curStyle = computed(() => textStyleOf(this.selectedElement()), /* @ts-ignore */
144991
145360
  ...(ngDevMode ? [{ debugName: "curStyle" }] : /* istanbul ignore next */ []));
145361
+ this.listKind = computed(() => {
145362
+ const element = this.selectedElement();
145363
+ return element ? elementBulletKind(element) : 'none';
145364
+ }, /* @ts-ignore */
145365
+ ...(ngDevMode ? [{ debugName: "listKind" }] : /* istanbul ignore next */ []));
144992
145366
  }
144993
145367
  isText() {
144994
145368
  return isTextElement(this.selectedElement());
@@ -145007,7 +145381,10 @@ class RibbonParagraphControlsComponent {
145007
145381
  }
145008
145382
  /** Toggle the paragraph list style (bullet / numbered) off when already set. */
145009
145383
  toggleList(kind) {
145010
- this.patch({ listType: this.curStyle()?.listType === kind ? 'none' : kind });
145384
+ if (!this.canEdit()) {
145385
+ return;
145386
+ }
145387
+ this.patch({ listType: this.listKind() === kind ? 'none' : kind });
145011
145388
  }
145012
145389
  /** Step the paragraph left-indent by `deltaPx` (clamped at 0). */
145013
145390
  changeIndent(deltaPx) {
@@ -145030,14 +145407,15 @@ class RibbonParagraphControlsComponent {
145030
145407
  patchTextStyle(this.editor, this.slideIndex(), this.selectedElement(), patch);
145031
145408
  }
145032
145409
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonParagraphControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
145033
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonParagraphControlsComponent, isStandalone: true, selector: "pptx-ribbon-paragraph-controls", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
145410
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonParagraphControlsComponent, isStandalone: true, selector: "pptx-ribbon-paragraph-controls", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
145034
145411
  <!-- List style: bullets + numbering -->
145035
145412
  <div class="pptx-rb-grp">
145036
145413
  <button
145037
145414
  type="button"
145038
145415
  class="pptx-rb-gb"
145039
- [disabled]="!isText()"
145040
- [ngClass]="curStyle()?.listType === 'bullet' ? 'bg-accent' : ''"
145416
+ [disabled]="!canEdit() || !isText()"
145417
+ [ngClass]="listKind() === 'bullet' ? 'bg-accent' : ''"
145418
+ [attr.aria-pressed]="listKind() === 'bullet'"
145041
145419
  [title]="'pptx.ribbon.bulletList' | translate"
145042
145420
  (click)="toggleList('bullet')"
145043
145421
  >
@@ -145046,8 +145424,9 @@ class RibbonParagraphControlsComponent {
145046
145424
  <button
145047
145425
  type="button"
145048
145426
  class="pptx-rb-gl"
145049
- [disabled]="!isText()"
145050
- [ngClass]="curStyle()?.listType === 'numbered' ? 'bg-accent' : ''"
145427
+ [disabled]="!canEdit() || !isText()"
145428
+ [ngClass]="listKind() === 'numbered' ? 'bg-accent' : ''"
145429
+ [attr.aria-pressed]="listKind() === 'numbered'"
145051
145430
  [title]="'pptx.notes.numberedList' | translate"
145052
145431
  (click)="toggleList('numbered')"
145053
145432
  >
@@ -145180,8 +145559,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145180
145559
  <button
145181
145560
  type="button"
145182
145561
  class="pptx-rb-gb"
145183
- [disabled]="!isText()"
145184
- [ngClass]="curStyle()?.listType === 'bullet' ? 'bg-accent' : ''"
145562
+ [disabled]="!canEdit() || !isText()"
145563
+ [ngClass]="listKind() === 'bullet' ? 'bg-accent' : ''"
145564
+ [attr.aria-pressed]="listKind() === 'bullet'"
145185
145565
  [title]="'pptx.ribbon.bulletList' | translate"
145186
145566
  (click)="toggleList('bullet')"
145187
145567
  >
@@ -145190,8 +145570,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145190
145570
  <button
145191
145571
  type="button"
145192
145572
  class="pptx-rb-gl"
145193
- [disabled]="!isText()"
145194
- [ngClass]="curStyle()?.listType === 'numbered' ? 'bg-accent' : ''"
145573
+ [disabled]="!canEdit() || !isText()"
145574
+ [ngClass]="listKind() === 'numbered' ? 'bg-accent' : ''"
145575
+ [attr.aria-pressed]="listKind() === 'numbered'"
145195
145576
  [title]="'pptx.notes.numberedList' | translate"
145196
145577
  (click)="toggleList('numbered')"
145197
145578
  >
@@ -145299,7 +145680,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145299
145680
  </select>
145300
145681
  `,
145301
145682
  }]
145302
- }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
145683
+ }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }] } });
145303
145684
 
145304
145685
  /**
145305
145686
  * ribbon-home-section.component.ts: the Home ribbon tab (Clipboard, Slides, Font
@@ -145596,6 +145977,7 @@ class RibbonHomeSectionComponent {
145596
145977
  <div class="flex flex-col items-center gap-0.5">
145597
145978
  <div class="flex items-center gap-1">
145598
145979
  <pptx-ribbon-paragraph-controls
145980
+ [canEdit]="canEdit()"
145599
145981
  [slideIndex]="slideIndex()"
145600
145982
  [selectedElement]="selectedElement()"
145601
145983
  />
@@ -145615,7 +145997,7 @@ class RibbonHomeSectionComponent {
145615
145997
  {{ 'pptx.shortcuts.group.editing' | translate }}
145616
145998
  </span>
145617
145999
  </div>
145618
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RibbonLayoutGalleryComponent, selector: "pptx-ribbon-layout-gallery", inputs: ["layoutOptions", "previews", "currentLayoutPath", "disabled"], outputs: ["select"] }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideClipboardPaste, selector: "svg[lucideClipboardPaste]" }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideFolderPlus, selector: "svg[lucideFolderPlus]" }, { kind: "component", type: LucideLayoutGrid, selector: "svg[lucideLayoutGrid]" }, { kind: "component", type: LucideLayoutTemplate, selector: "svg[lucideLayoutTemplate]" }, { kind: "component", type: LucidePaintbrush, selector: "svg[lucidePaintbrush]" }, { kind: "component", type: LucideRotateCcw, selector: "svg[lucideRotateCcw]" }, { kind: "component", type: LucideScissors, selector: "svg[lucideScissors]" }, { 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: RibbonEditingSectionComponent, selector: "pptx-ribbon-editing-section", outputs: ["toggleFindReplace", "selectAll"] }, { kind: "directive", type: AnchoredPopupDirective, selector: "[pptxAnchoredPopup]", inputs: ["pptxAnchoredPopup", "pptxAnchoredPopupAlignRight"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
146000
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RibbonLayoutGalleryComponent, selector: "pptx-ribbon-layout-gallery", inputs: ["layoutOptions", "previews", "currentLayoutPath", "disabled"], outputs: ["select"] }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideClipboardPaste, selector: "svg[lucideClipboardPaste]" }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideFolderPlus, selector: "svg[lucideFolderPlus]" }, { kind: "component", type: LucideLayoutGrid, selector: "svg[lucideLayoutGrid]" }, { kind: "component", type: LucideLayoutTemplate, selector: "svg[lucideLayoutTemplate]" }, { kind: "component", type: LucidePaintbrush, selector: "svg[lucidePaintbrush]" }, { kind: "component", type: LucideRotateCcw, selector: "svg[lucideRotateCcw]" }, { kind: "component", type: LucideScissors, selector: "svg[lucideScissors]" }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement", "canEdit"] }, { kind: "component", type: RibbonEditingSectionComponent, selector: "pptx-ribbon-editing-section", outputs: ["toggleFindReplace", "selectAll"] }, { kind: "directive", type: AnchoredPopupDirective, selector: "[pptxAnchoredPopup]", inputs: ["pptxAnchoredPopup", "pptxAnchoredPopupAlignRight"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
145619
146001
  }
145620
146002
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonHomeSectionComponent, decorators: [{
145621
146003
  type: Component,
@@ -145831,6 +146213,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145831
146213
  <div class="flex flex-col items-center gap-0.5">
145832
146214
  <div class="flex items-center gap-1">
145833
146215
  <pptx-ribbon-paragraph-controls
146216
+ [canEdit]="canEdit()"
145834
146217
  [slideIndex]="slideIndex()"
145835
146218
  [selectedElement]="selectedElement()"
145836
146219
  />
@@ -147064,6 +147447,7 @@ class RibbonContentComponent {
147064
147447
  />
147065
147448
  <span class="pptx-rb-sep"></span>
147066
147449
  <pptx-ribbon-paragraph-controls
147450
+ [canEdit]="canEdit()"
147067
147451
  [slideIndex]="slideIndex()"
147068
147452
  [selectedElement]="selectedElement()"
147069
147453
  />
@@ -147079,7 +147463,7 @@ class RibbonContentComponent {
147079
147463
  />
147080
147464
  }
147081
147465
  }
147082
- `, 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", "savePpt", "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 }); }
147466
+ `, 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", "savePpt", "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", "canEdit"] }, { 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 }); }
147083
147467
  }
147084
147468
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonContentComponent, decorators: [{
147085
147469
  type: Component,
@@ -147182,6 +147566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
147182
147566
  />
147183
147567
  <span class="pptx-rb-sep"></span>
147184
147568
  <pptx-ribbon-paragraph-controls
147569
+ [canEdit]="canEdit()"
147185
147570
  [slideIndex]="slideIndex()"
147186
147571
  [selectedElement]="selectedElement()"
147187
147572
  />
@@ -168580,7 +168965,7 @@ class SlideSorterOverlayComponent {
168580
168965
  return hiddenSlideCue(this.isHiddenSlide(slide), 'sorter', index);
168581
168966
  }
168582
168967
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideSorterOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
168583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideSorterOverlayComponent, isStandalone: true, selector: "pptx-slide-sorter-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 }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", closed: "closed", deleteSlide: "deleteSlide", duplicateSlide: "duplicateSlide", toggleHiddenSlide: "toggleHiddenSlide" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<!-- Backdrop -->\n<div class=\"pptx-ng-sorter-backdrop\" (click)=\"onBackdropClick($event)\">\n\t<!-- Modal panel -->\n\t<div class=\"pptx-ng-sorter-panel\" (click)=\"$event.stopPropagation()\">\n\t\t<!-- Header -->\n\t\t<header class=\"pptx-ng-sorter-header\">\n\t\t\t<h2 class=\"pptx-ng-sorter-title\">{{ 'pptx.slideSorter.title' | translate }}</h2>\n\t\t\t<span class=\"pptx-ng-sorter-count\">{{\n\t\t\t\t'pptx.slideSorter.slideCount' | translate: { count: slides().length }\n\t\t\t}}</span>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-ng-sorter-close\"\n\t\t\t\t[attr.aria-label]=\"'pptx.slideSorter.close' | translate\"\n\t\t\t\t(click)=\"closed.emit()\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth=\"16\"\n\t\t\t\t\theight=\"16\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</header>\n\n\t\t<!-- Scrollable grid -->\n\t\t<div class=\"pptx-ng-sorter-grid-scroll\">\n\t\t\t<div class=\"pptx-ng-sorter-grid\" [ngStyle]=\"gridStyle()\">\n\t\t\t\t@for (slide of slides(); track slide.id; let i = $index) {\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-sorter-cell\"\n\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t[class.is-hidden]=\"hidden.hidden\"\n\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t[attr.aria-current]=\"i === activeIndex() ? 'true' : null\"\n\t\t\t\t\t\t(click)=\"onThumbClick(i)\"\n\t\t\t\t\t\t(contextmenu)=\"onThumbContextMenu($event, i)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Thumbnail clipping wrapper -->\n\t\t\t\t\t\t<div class=\"pptx-ng-sorter-thumb-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Slide number badge, struck through with the shared diagonal\n\t\t\t\t\t\t slash when hidden (PowerPoint's own cue). -->\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"pptx-ng-sorter-index\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t>\n\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t<span class=\"pptx-ng-sorter-hidden\" [id]=\"hidden.labelId\">{{\n\t\t\t\t\t\t\t\thiddenLabelKey | translate\n\t\t\t\t\t\t\t}}</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</div>\n\t</div>\n\n\t@if (contextMenu(); as menu) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-sorter-menu-backdrop\"\n\t\t\t[attr.aria-label]=\"'pptx.overflow.closeMenu' | translate\"\n\t\t\t(click)=\"closeContextMenu()\"\n\t\t\t(contextmenu)=\"$event.preventDefault(); closeContextMenu()\"\n\t\t></button>\n\t\t<div\n\t\t\tclass=\"pptx-ng-sorter-context-menu\"\n\t\t\t[style.left.px]=\"menu.x\"\n\t\t\t[style.top.px]=\"menu.y\"\n\t\t\trole=\"menu\"\n\t\t>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuDuplicate()\">\n\t\t\t\t{{ 'pptx.slideMenu.duplicate' | translate }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuToggleHidden()\">\n\t\t\t\t{{\n\t\t\t\t\t(contextMenuTargetHidden() ? 'pptx.slideMenu.show' : 'pptx.slideMenu.hide') | translate\n\t\t\t\t}}\n\t\t\t</button>\n\t\t\t<div class=\"pptx-ng-sorter-context-menu-sep\"></div>\n\t\t\t<button type=\"button\" role=\"menuitem\" class=\"is-danger\" (click)=\"menuDelete()\">\n\t\t\t\t{{ 'pptx.slideMenu.delete' | translate }}\n\t\t\t</button>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{display:inline-block;padding:0 .2rem;font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-hidden{font-size:.5625rem;text-transform:uppercase;letter-spacing:.05em;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-menu-backdrop{position:fixed;inset:0;z-index:59;border:none;padding:0;background:transparent;cursor:default}.pptx-ng-sorter-context-menu{position:fixed;z-index:60;min-width:160px;padding:.25rem;border:1px solid rgba(255,255,255,.12);border-radius:.375rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 8px 24px #00000080}.pptx-ng-sorter-context-menu button{display:block;width:100%;padding:.375rem .625rem;border:none;border-radius:.25rem;background:transparent;color:inherit;text-align:left;font-size:.75rem;cursor:pointer}.pptx-ng-sorter-context-menu button:hover{background:#ffffff14}.pptx-ng-sorter-context-menu button.is-danger{color:#f87171}.pptx-ng-sorter-context-menu-sep{margin:.25rem .125rem;border-top:1px solid rgba(255,255,255,.12)}\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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
168968
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideSorterOverlayComponent, isStandalone: true, selector: "pptx-slide-sorter-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 }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", closed: "closed", deleteSlide: "deleteSlide", duplicateSlide: "duplicateSlide", toggleHiddenSlide: "toggleHiddenSlide" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<!-- Backdrop -->\n<div class=\"pptx-ng-sorter-backdrop\" (click)=\"onBackdropClick($event)\">\n\t<!-- Modal panel -->\n\t<div class=\"pptx-ng-sorter-panel\" (click)=\"$event.stopPropagation()\">\n\t\t<!-- Header -->\n\t\t<header class=\"pptx-ng-sorter-header\">\n\t\t\t<h2 class=\"pptx-ng-sorter-title\">{{ 'pptx.slideSorter.title' | translate }}</h2>\n\t\t\t<span class=\"pptx-ng-sorter-count\">{{\n\t\t\t\t'pptx.slideSorter.slideCount' | translate: { count: slides().length }\n\t\t\t}}</span>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-ng-sorter-close\"\n\t\t\t\t[attr.aria-label]=\"'pptx.slideSorter.close' | translate\"\n\t\t\t\t(click)=\"closed.emit()\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth=\"16\"\n\t\t\t\t\theight=\"16\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</header>\n\n\t\t<!-- Scrollable grid -->\n\t\t<div class=\"pptx-ng-sorter-grid-scroll\">\n\t\t\t<div class=\"pptx-ng-sorter-grid\" [ngStyle]=\"gridStyle()\">\n\t\t\t\t@for (slide of slides(); track slide.id; let i = $index) {\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-sorter-cell\"\n\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t[class.is-hidden]=\"hidden.hidden\"\n\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t[attr.aria-current]=\"i === activeIndex() ? 'true' : null\"\n\t\t\t\t\t\t(click)=\"onThumbClick(i)\"\n\t\t\t\t\t\t(contextmenu)=\"onThumbContextMenu($event, i)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Thumbnail clipping wrapper -->\n\t\t\t\t\t\t<div class=\"pptx-ng-sorter-thumb-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Slide number badge, struck through with the shared diagonal\n\t\t\t\t\t\t slash when hidden (PowerPoint's own cue). -->\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"pptx-ng-sorter-index\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t>\n\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t<span class=\"pptx-ng-sorter-hidden\" [id]=\"hidden.labelId\">{{\n\t\t\t\t\t\t\t\thiddenLabelKey | translate\n\t\t\t\t\t\t\t}}</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</div>\n\t</div>\n\n\t@if (contextMenu(); as menu) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-sorter-menu-backdrop\"\n\t\t\t[attr.aria-label]=\"'pptx.overflow.closeMenu' | translate\"\n\t\t\t(click)=\"closeContextMenu()\"\n\t\t\t(contextmenu)=\"$event.preventDefault(); closeContextMenu()\"\n\t\t></button>\n\t\t<div\n\t\t\tclass=\"pptx-ng-sorter-context-menu\"\n\t\t\t[style.left.px]=\"menu.x\"\n\t\t\t[style.top.px]=\"menu.y\"\n\t\t\trole=\"menu\"\n\t\t>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuDuplicate()\">\n\t\t\t\t{{ 'pptx.slideMenu.duplicate' | translate }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuToggleHidden()\">\n\t\t\t\t{{\n\t\t\t\t\t(contextMenuTargetHidden() ? 'pptx.slideMenu.show' : 'pptx.slideMenu.hide') | translate\n\t\t\t\t}}\n\t\t\t</button>\n\t\t\t<div class=\"pptx-ng-sorter-context-menu-sep\"></div>\n\t\t\t<button type=\"button\" role=\"menuitem\" class=\"is-danger\" (click)=\"menuDelete()\">\n\t\t\t\t{{ 'pptx.slideMenu.delete' | translate }}\n\t\t\t</button>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{display:inline-block;padding:0 .2rem;font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-hidden{font-size:.5625rem;text-transform:uppercase;letter-spacing:.05em;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-menu-backdrop{position:fixed;inset:0;z-index:59;border:none;padding:0;background:transparent;cursor:default}.pptx-ng-sorter-context-menu{position:fixed;z-index:60;min-width:160px;padding:.25rem;border:1px solid rgba(255,255,255,.12);border-radius:.375rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 8px 24px #00000080}.pptx-ng-sorter-context-menu button{display:block;width:100%;padding:.375rem .625rem;border:none;border-radius:.25rem;background:transparent;color:inherit;text-align:left;font-size:.75rem;cursor:pointer}.pptx-ng-sorter-context-menu button:hover{background:#ffffff14}.pptx-ng-sorter-context-menu button.is-danger{color:#f87171}.pptx-ng-sorter-context-menu-sep{margin:.25rem .125rem;border-top:1px solid rgba(255,255,255,.12)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
168584
168969
  }
168585
168970
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideSorterOverlayComponent, decorators: [{
168586
168971
  type: Component,
@@ -169001,7 +169386,7 @@ class SlidesPanelComponent {
169001
169386
  return hiddenSlideCue(slide.hidden, 'rail', index);
169002
169387
  }
169003
169388
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlidesPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
169004
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\tSection highlight colour (p15:sectionPr/@clr). Core parses and\n\t\t\t\t\t\t\t\t\tround-trips it; only React was drawing it.\n\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t@if (item.section?.color; as sectionColor) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-swatch\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-section-color\n\t\t\t\t\t\t\t\t\t\t[style.background-color]=\"sectionColor\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column). Struck through with the shared\n\t\t\t\t\t\t\t\t diagonal slash when the slide is hidden, which is PowerPoint's own\n\t\t\t\t\t\t\t\t cue and, unlike the dimming, is not a colour-only signal. -->\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-num\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t\t\t>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[style.opacity]=\"hidden.hidden ? dimOpacity : null\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t\t\t\t<!-- Announced through aria-describedby, so the accessible name\n\t\t\t\t\t\t\t\t\t\t stays exactly \"Go to slide {{ i + 1 }}\". -->\n\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-hidden\" [id]=\"hidden.labelId\">\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M1 1l22 22\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-sr-only\">{{ hiddenLabelKey | translate }}</span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-swatch{display:inline-block;flex:0 0 auto;width:.5rem;height:.5rem;border-radius:9999px}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #3b82f6);outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{position:relative;overflow:hidden;border-radius:2px}.pptx-ng-spanel-hidden{position:absolute;right:2px;bottom:2px;z-index:10;display:inline-flex;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45))}.pptx-ng-spanel-hidden svg{width:.75rem;height:.75rem}.pptx-ng-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #e5e5e5);font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #e5e5e5)}\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: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash], svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
169389
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\tSection highlight colour (p15:sectionPr/@clr). Core parses and\n\t\t\t\t\t\t\t\t\tround-trips it; only React was drawing it.\n\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t@if (item.section?.color; as sectionColor) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-swatch\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-section-color\n\t\t\t\t\t\t\t\t\t\t[style.background-color]=\"sectionColor\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column). Struck through with the shared\n\t\t\t\t\t\t\t\t diagonal slash when the slide is hidden, which is PowerPoint's own\n\t\t\t\t\t\t\t\t cue and, unlike the dimming, is not a colour-only signal. -->\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-num\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t\t\t>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[style.opacity]=\"hidden.hidden ? dimOpacity : null\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t\t\t\t<!-- Announced through aria-describedby, so the accessible name\n\t\t\t\t\t\t\t\t\t\t stays exactly \"Go to slide {{ i + 1 }}\". -->\n\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-hidden\" [id]=\"hidden.labelId\">\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M1 1l22 22\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-sr-only\">{{ hiddenLabelKey | translate }}</span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-swatch{display:inline-block;flex:0 0 auto;width:.5rem;height:.5rem;border-radius:9999px}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #3b82f6);outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{position:relative;overflow:hidden;border-radius:2px}.pptx-ng-spanel-hidden{position:absolute;right:2px;bottom:2px;z-index:10;display:inline-flex;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45))}.pptx-ng-spanel-hidden svg{width:.75rem;height:.75rem}.pptx-ng-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #e5e5e5);font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #e5e5e5)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash], svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
169005
169390
  }
169006
169391
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlidesPanelComponent, decorators: [{
169007
169392
  type: Component,
@@ -170629,7 +171014,7 @@ class SlideDiffThumbnailsComponent {
170629
171014
  </div>
170630
171015
  }
170631
171016
  </div>
170632
- `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ 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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
171017
+ `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "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: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
170633
171018
  }
170634
171019
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideDiffThumbnailsComponent, decorators: [{
170635
171020
  type: Component,
@@ -175772,6 +176157,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
175772
176157
  }]
175773
176158
  }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], aiExportVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiExportVisible", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
175774
176159
 
176160
+ /** Public insertion uses the same synchronous commit and editor transaction as the canvas. */
176161
+ function insertPublicElement(element, target, editor, slideIndex, commitPendingText) {
176162
+ const prepared = prepareElementForInsertion(element, target);
176163
+ if (!prepared) {
176164
+ return undefined;
176165
+ }
176166
+ commitPendingText();
176167
+ editor.addElement(slideIndex, prepared);
176168
+ return prepared.id;
176169
+ }
176170
+
175775
176171
  /* oxlint-disable eslint/one-var -- pre-existing throughout this file; independent concerns, not one statement */
175776
176172
  /**
175777
176173
  * PowerPointViewerComponent: Angular port of the React `PowerPointViewer.tsx`
@@ -175867,6 +176263,12 @@ class PowerPointViewerComponent {
175867
176263
  */
175868
176264
  this.fileName = input(undefined, /* @ts-ignore */
175869
176265
  ...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
176266
+ /** Unscaled decorative viewport padding per side; omission preserves defaults. */
176267
+ this.fitPadding = input(undefined, /* @ts-ignore */
176268
+ ...(ngDevMode ? [{ debugName: "fitPadding" }] : /* istanbul ignore next */ []));
176269
+ /** Fit-factor ceiling, independent of user zoom; null permits enlargement. */
176270
+ this.maxFitScale = input(undefined, /* @ts-ignore */
176271
+ ...(ngDevMode ? [{ debugName: "maxFitScale" }] : /* istanbul ignore next */ []));
175870
176272
  /**
175871
176273
  * Recovery autosave: after an edit the deck is re-serialised (always as a
175872
176274
  * plain, unencrypted package, because recovery has no password) and stashed
@@ -176106,9 +176508,13 @@ class PowerPointViewerComponent {
176106
176508
  * read-only recommendation (`p:modifyVerifier` / "Mark as Final"; lifted by
176107
176509
  * the read-only banner's "Edit anyway", see {@link LoadNoticesService}).
176108
176510
  */
176109
- this.canEdit = computed(() => this.canEditInput() &&
176511
+ this.hasEditPermission = computed(() => this.canEditInput() &&
176110
176512
  (!this.viewerOpts.options().trust.openInProtectedView || this.protectedViewDismissed()) &&
176111
176513
  !this.loadNotices.lockActive(), /* @ts-ignore */
176514
+ ...(ngDevMode ? [{ debugName: "hasEditPermission" }] : /* istanbul ignore next */ []));
176515
+ this.editingRequested = signal(true, /* @ts-ignore */
176516
+ ...(ngDevMode ? [{ debugName: "editingRequested" }] : /* istanbul ignore next */ []));
176517
+ this.canEdit = computed(() => this.hasEditPermission() && this.editingRequested(), /* @ts-ignore */
176112
176518
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
176113
176519
  /** Whether the Protected View banner should show: host allows editing, the option still blocks it, and the user hasn't dismissed it yet. */
176114
176520
  this.protectedViewActive = computed(() => this.canEditInput() &&
@@ -176145,8 +176551,8 @@ class PowerPointViewerComponent {
176145
176551
  */
176146
176552
  this.audienceSessionEnded = signal(false, /* @ts-ignore */
176147
176553
  ...(ngDevMode ? [{ debugName: "audienceSessionEnded" }] : /* istanbul ignore next */ []));
176148
- /** Slides to display: the editable deck when `canEdit`, else the loaded deck. */
176149
- this.displaySlides = computed(() => this.canEdit() ? this.editor.slides() : this.loader.slides(), /* @ts-ignore */
176554
+ /** Preview changes interaction, not which permitted live deck is displayed. */
176555
+ this.displaySlides = computed(() => this.hasEditPermission() ? this.editor.slides() : this.loader.slides(), /* @ts-ignore */
176150
176556
  ...(ngDevMode ? [{ debugName: "displaySlides" }] : /* istanbul ignore next */ []));
176151
176557
  this.slideCount = computed(() => this.displaySlides().length, /* @ts-ignore */
176152
176558
  ...(ngDevMode ? [{ debugName: "slideCount" }] : /* istanbul ignore next */ []));
@@ -176156,7 +176562,7 @@ class PowerPointViewerComponent {
176156
176562
  * consumer that needs the COMPLETE slide (export, print, slide thumbnails,
176157
176563
  * accessibility) renders this instead so template elements are not lost.
176158
176564
  */
176159
- this.mergedSlides = computed(() => this.canEdit()
176565
+ this.mergedSlides = computed(() => this.hasEditPermission()
176160
176566
  ? buildSaveSlides(this.editor.slides(), this.editor.templateElementsBySlideId())
176161
176567
  : this.loader.slides(), /* @ts-ignore */
176162
176568
  ...(ngDevMode ? [{ debugName: "mergedSlides" }] : /* istanbul ignore next */ []));
@@ -176168,7 +176574,7 @@ class PowerPointViewerComponent {
176168
176574
  /** Inherited template (master/layout) elements for the active slide, when editing. */
176169
176575
  this.activeTemplateElements = computed(() => {
176170
176576
  const slide = this.activeSlide();
176171
- if (!this.canEdit() || !slide) {
176577
+ if (!this.hasEditPermission() || !slide) {
176172
176578
  return [];
176173
176579
  }
176174
176580
  return this.editor.templateElementsBySlideId()[slide.id] ?? [];
@@ -176966,7 +177372,7 @@ class PowerPointViewerComponent {
176966
177372
  // component (canEdit, the host `content` input, the File ▸ Open override,
176967
177373
  // the editor's slides + template elements, and the contentChange emitter).
176968
177374
  this.fileIO.bind({
176969
- canEdit: () => this.canEdit(),
177375
+ canEdit: () => this.hasEditPermission(),
176970
177376
  content: () => this.content(),
176971
177377
  onOpenFile: () => this.onOpenFile(),
176972
177378
  slides: () => this.editor.slides(),
@@ -177382,6 +177788,12 @@ class PowerPointViewerComponent {
177382
177788
  }
177383
177789
  /** Switch the viewer mode (e.g. 'edit', 'preview', 'present'). */
177384
177790
  setMode(mode) {
177791
+ if (mode === 'preview' && this.canEdit()) {
177792
+ this.mainEl()?.nativeElement.querySelector('[data-inline-editor]')?.blur();
177793
+ }
177794
+ if (mode !== 'present') {
177795
+ this.editingRequested.set(mode !== 'preview');
177796
+ }
177385
177797
  if (mode === 'present') {
177386
177798
  this.presentationMode.present();
177387
177799
  }
@@ -177531,6 +177943,18 @@ class PowerPointViewerComponent {
177531
177943
  const s = this.displaySlides()[idx];
177532
177944
  return s?.elements.find((e) => e.id === elementId);
177533
177945
  }
177946
+ /** Insert a defensive copy into the active ordinary editable slide. */
177947
+ addElement(element) {
177948
+ return insertPublicElement(element, {
177949
+ canEdit: this.canEdit(),
177950
+ mode: this.getMode(),
177951
+ hasActiveSlide: !this.loader.loading() && !this.loader.error() && Boolean(this.activeSlide()),
177952
+ editTemplateMode: this.editor.editTemplateMode(),
177953
+ }, this.editor, this.activeSlideIndex(), () => {
177954
+ // Blur synchronously emits the existing canvas textCommit before insertion.
177955
+ this.mainEl()?.nativeElement.querySelector('[data-inline-editor]')?.blur();
177956
+ });
177957
+ }
177534
177958
  /** Update one or more properties of an element by ID. */
177535
177959
  updateElement(elementId, updates) {
177536
177960
  this.editor.updateElement(this.activeSlideIndex(), elementId, updates);
@@ -177886,7 +178310,7 @@ class PowerPointViewerComponent {
177886
178310
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
177887
178311
  }
177888
178312
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
177889
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", 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: `
178313
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", 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 }, fitPadding: { classPropertyName: "fitPadding", publicName: "fitPadding", isSignal: true, isRequired: false, transformFunction: null }, maxFitScale: { classPropertyName: "maxFitScale", publicName: "maxFitScale", 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: `
177890
178314
  <div
177891
178315
  class="pptx-ng-viewer"
177892
178316
  [ngClass]="rootClasses()"
@@ -178141,6 +178565,8 @@ class PowerPointViewerComponent {
178141
178565
  [canvasSize]="loader.canvasSize()"
178142
178566
  [mediaDataUrls]="loader.mediaDataUrls()"
178143
178567
  [zoom]="zoomSvc.zoom()"
178568
+ [fitPadding]="fitPadding()"
178569
+ [maxFitScale]="maxFitScale()"
178144
178570
  [editable]="canEdit()"
178145
178571
  [selectedIds]="editor.selectedIds()"
178146
178572
  [showGrid]="showGrid()"
@@ -178840,7 +179266,7 @@ class PowerPointViewerComponent {
178840
179266
  (dismissAll)="loadNotices.dismissAllToasts()"
178841
179267
  />
178842
179268
  </div>
178843
- `, 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", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "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", "modernCommentAuthors"], 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", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { 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", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { 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", "savePpt", "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", "openAnimationPanel", "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 */
179269
+ `, 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", "fitPadding", "maxFitScale", "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", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "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", "modernCommentAuthors"], 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", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { 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", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { 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", "savePpt", "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", "openAnimationPanel", "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 */
178844
179270
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] }); }
178845
179271
  }
178846
179272
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -179160,6 +179586,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
179160
179586
  [canvasSize]="loader.canvasSize()"
179161
179587
  [mediaDataUrls]="loader.mediaDataUrls()"
179162
179588
  [zoom]="zoomSvc.zoom()"
179589
+ [fitPadding]="fitPadding()"
179590
+ [maxFitScale]="maxFitScale()"
179163
179591
  [editable]="canEdit()"
179164
179592
  [selectedIds]="editor.selectedIds()"
179165
179593
  [showGrid]="showGrid()"
@@ -179861,7 +180289,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
179861
180289
  </div>
179862
180290
  `,
179863
180291
  }]
179864
- }], 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: [{
180292
+ }], 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 }] }], fitPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitPadding", required: false }] }], maxFitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFitScale", 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: [{
179865
180293
  type: HostListener,
179866
180294
  args: ['document:keydown', ['$event']]
179867
180295
  }], clearCacheOnUnload: [{
@@ -182140,4 +182568,4 @@ function cn(...values) {
182140
182568
  */
182141
182569
 
182142
182570
  export { CollaborationService as $, AFTER_ANIMATION_VALUES as A, AnimationAuthorPanelComponent as B, AnimationPanelComponent as C, AnimationPlaybackService as D, AutosaveRecoveryDialogComponent as E, AutosaveService as F, BroadcastDialogComponent as G, CHART_EDITOR_STYLES as H, CURSOR_PALETTE as I, CanvasFitService as J, ChartAxisOptionsComponent as K, ChartAxisStyleOptionsComponent as L, ChartComboTypeOptionsComponent as M, ChartDataEditorComponent as N, ChartDataLabelOptionsComponent as O, ChartDatapointMarkerOptionsComponent as P, ChartDatapointOptionsComponent as Q, ChartDisplayOptionsComponent as R, ChartElementViewComponent as S, ChartErrorBarOptionsComponent as T, ChartMarkerOptionsComponent as U, ChartPartSelectionService as V, ChartPrimitivesComponent as W, ChartRendererComponent as X, ChartTrendlineOptionsComponent as Y, ChartTypeSelectorComponent as Z, CollaborationCursorsComponent as _, ALIGN_OPTIONS as a, InsertSmartArtDialogComponent as a$, ColorChangedImageComponent as a0, CommentMarkersOverlayComponent as a1, CommentsPanelComponent as a2, CommentsService as a3, ComparePanelComponent as a4, ConnectorRendererComponent as a5, ConnectorTextOverlayComponent as a6, CustomShowsComponent as a7, DEFAULT_BOUNDS as a8, DEFAULT_BROADCAST_SERVER_URL as a9, EditorToolbarComponent as aA, EffectsPanelComponent as aB, ElementRendererComponent as aC, EmbeddedFontsService as aD, EncryptedFileDialogComponent as aE, EquationEditorDialogComponent as aF, EquationRendererComponent as aG, EquationTemplateGalleryComponent as aH, ExportProgressModalComponent as aI, ExportService as aJ, FieldContextService as aK, FindBarComponent as aL, FindReplaceBarComponent as aM, FollowModeBarComponent as aN, FontEmbeddingListComponent as aO, FontEmbeddingPanelComponent as aP, GALLERY_THEME_PRESETS as aQ, GOOGLE_WEBFONTS_LINK_ID as aR, GRIDLINE_COLOR$1 as aS, GoogleWebfontsService as aT, GradientPickerComponent as aU, HANDOUT_OPTIONS as aV, HeaderFooterDialogComponent as aW, HyperlinkDialogComponent as aX, ImagePropertiesPanelComponent as aY, InkDrawingService as aZ, InkRendererComponent as a_, DEFAULT_CANVAS_HEIGHT as aa, DEFAULT_CANVAS_WIDTH as ab, DEFAULT_COLOR_SCHEME as ac, DEFAULT_FILL_COLOR$1 as ad, DEFAULT_LAYOUT as ae, DEFAULT_PALETTE$1 as af, DEFAULT_PATTERN_FILL_PRESET as ag, DEFAULT_PRINT_SETTINGS as ah, DEFAULT_SLIDE_BACKGROUND as ai, DEFAULT_STROKE_COLOR as aj, DEFAULT_STYLE as ak, DEFAULT_TABLE_ROW_HEIGHT as al, DEFAULT_TEXT_COLOR$2 as am, DEFAULT_VIEWER_PROFILE as an, DIRECTIONAL_PRESETS as ao, DIRECTION_OPTIONS as ap, DocumentPropertiesCardComponent as aq, EFFECT_SOUND_CATALOGUE as ar, EMBEDDED_FONTS_STYLE_ID as as, EMPHASIS_PRESETS as at, ENTRANCE_PRESETS as au, TEMPLATES as av, EXIT_PRESETS as aw, EditorContextMenuComponent as ax, EditorHistory as ay, EditorStateService as az, ANIMATION_PRESET_CATEGORIES as b, RibbonArrangeSectionComponent as b$, InspectorPaneHeaderComponent as b0, InspectorPanelComponent as b1, IsMobileService as b2, KeepAnnotationsDialogComponent as b3, LOCALE_CATALOG as b4, LONG_PRESS_DURATION_MS as b5, LONG_PRESS_MOVE_TOLERANCE_PX as b6, LoadContentService as b7, LocalPresencePublisher as b8, MAX_ZOOM_SCALE as b9, PX_PER_INCH as bA, PasswordProtectionDialogComponent as bB, PasswordStrengthMeterComponent as bC, PowerPointViewerComponent as bD, PresentToolbarAutoHide as bE, PresentationAnnotationOverlayComponent as bF, PresentationAnnotationsService as bG, PresentationOverlayComponent as bH, PresentationPropertiesPanelComponent as bI, PresentationSettingsCardComponent as bJ, PresentationSubtitleBarComponent as bK, PresentationToolbarComponent as bL, PresentationTransitionOverlayComponent as bM, PresenterViewComponent as bN, PresenterWindowService as bO, PrintDialogComponent as bP, PrintService as bQ, PrintSettingsPanelComponent as bR, PropertiesDialogComponent as bS, REPEAT_MODE_OPTIONS as bT, RESIZE_HANDLES as bU, RULER_FONT_SIZE as bV, RULER_THICKNESS as bW, ReadingViewOverlayComponent as bX, RemoteSelectionOverlayComponent as bY, RibbonAnimationGalleryComponent as bZ, RibbonAnimationsSectionComponent as b_, MIN_ZOOM_SCALE as ba, MOTION_PATH_COLUMNS as bb, MediaPreviewComponent as bc, MediaPropertiesPanelComponent as bd, MediaRendererComponent as be, MediaTrimTimelineComponent as bf, MobileBottomBarComponent as bg, MobileMenuSheetComponent as bh, MobilePresenterViewComponent as bi, MobileSheetComponent as bj, MobileSlidesSheetComponent as bk, MobileToolbarComponent as bl, ModalDialogComponent as bm, Model3DRendererComponent as bn, NotesHandoutCardComponent as bo, NotesPanelComponent as bp, NotesToolbarComponent as bq, OleRendererComponent as br, OutlineViewOverlayComponent as bs, POWER_POINT_VIEWER_PROVIDERS as bt, PPTX_OPEN_ACCEPT as bu, PRESENTATION_OPEN_EXTENSIONS as bv, PRESENTER_CHANNEL_NAME as bw, PRESENTER_MSG_ORIGIN as bx, PRESENTER_TIMER_SEGMENT_MS as by, PX_PER_CM as bz, AUDIENCE_HASH as c, TABLE_STRUCTURE_TOGGLES as c$, RibbonColorPopoverComponent as c0, RibbonComponent as c1, RibbonDesignSectionComponent as c2, RibbonDrawSectionComponent as c3, RibbonDrawingGroupComponent as c4, RibbonEditingSectionComponent as c5, RibbonFileSectionComponent as c6, RibbonFontControlsComponent as c7, RibbonHomeSectionComponent as c8, RibbonHyperlinkButtonComponent as c9, SettingsAppearanceTabComponent as cA, SettingsDialogComponent as cB, SettingsLanguageTabComponent as cC, ShareDialogComponent as cD, ShortcutPanelComponent as cE, ShowOptionsFieldsetComponent as cF, ShowSlidesFieldsetComponent as cG, SignatureStrippedDialogComponent as cH, SignaturesPanelComponent as cI, SignaturesService as cJ, SlideBackgroundCardComponent as cK, SlideCanvasComponent as cL, SlideDefaultInspectorComponent as cM, SlideDiffChangesComponent as cN, SlideDiffRowComponent as cO, SlideDiffThumbnailsComponent as cP, SlideSizeCardComponent as cQ, SlideSorterOverlayComponent as cR, SlideThemeOverridePanelComponent as cS, SlideTransitionCardComponent as cT, SlidesPanelComponent as cU, SmartArt3DRendererComponent as cV, SmartArt3DService as cW, SmartArtPreviewComponent as cX, SmartArtPropertiesComponent as cY, SmartArtRendererComponent as cZ, StatusBarComponent as c_, RibbonInsertFieldsComponent as ca, RibbonInsertSectionComponent as cb, RibbonMotionPathGalleryComponent as cc, RibbonParagraphControlsComponent as cd, RibbonPrimaryRowComponent as ce, RibbonReviewSectionComponent as cf, RibbonShapeExtrasComponent as cg, RibbonSlideshowSectionComponent as ch, RibbonTransitionsSectionComponent as ci, RibbonViewSectionComponent as cj, RulerGuidesService as ck, SEQUENCE_OPTIONS as cl, SEVERITY_GROUPS as cm, SEVERITY_LABELS as cn, SHORTCUT_REFERENCE_ITEMS as co, SLIDE_TRANSITION_KEYFRAMES as cp, DEFAULT_PALETTE as cq, PALETTES$1 as cr, SMART_ART_COLOR_SCHEMES as cs, SMART_ART_STYLE_OPTIONS as ct, SUB_ITEM_LABEL as cu, SVG_WARP_PRESETS as cv, SWIPE_MAX_VERTICAL_PX as cw, SWIPE_THRESHOLD_PX as cx, SelectionPaneComponent as cy, SetUpSlideShowDialogComponent as cz, AUDIENCE_NONCE_KEY as d, alignPatch as d$, TEXT_3D_BOTTOM_BEVEL_KEYS as d0, TEXT_3D_TOP_BEVEL_KEYS as d1, TEXT_DIRECTION_OPTIONS$1 as d2, THEME_CATALOG as d3, TIMING_CURVE_OPTIONS as d4, TRIGGER_OPTIONS as d5, TYPE_LABELS as d6, TableCellAdvancedFillComponent as d7, TableCellFormattingComponent as d8, TableDataEditorComponent as d9, ViewerExportService as dA, ViewerExtraDialogsComponent as dB, ViewerFileIOService as dC, ViewerFindReplaceService as dD, ViewerFormatPainterService as dE, ViewerInspectorPanelService as dF, ViewerKeyboardService as dG, ViewerMobileSheetService as dH, ViewerPresentationModeService as dI, ViewerThemeGalleryService as dJ, ViewerTouchGesturesService as dK, ViewerZoomService as dL, WEBM_MIME_CANDIDATES as dM, WriteBackScheduler as dN, ZERO_LINE_COLOR as dO, ZoomNavigationService as dP, ZoomRendererComponent as dQ, ZoomTargetService as dR, addCategory as dS, addCommentToList as dT, addGradientStopPatch as dU, addItem as dV, addSeries as dW, addSubItem as dX, advanceStep as dY, affordanceElements as dZ, aiToggleVisible as d_, TablePropertiesComponent as da, TableRendererComponent as db, TableResizeOverlayComponent as dc, TableSelectionService as dd, TagsCardComponent as de, Text3DBevelSectionComponent as df, Text3DPanelComponent as dg, TextAdvancedPanelComponent as dh, ThemeEditorFieldsComponent as di, ThemeGalleryComponent as dj, ThemeSelectorCardComponent as dk, TitleBarComponent as dl, TitleBarSearchComponent as dm, TransitionDirectionPickerComponent as dn, TransitionPreviewComponent as dp, VALIGN_OPTIONS as dq, VIEWER_THEME as dr, VersionHistoryPanelComponent as ds, ViewerCanvasEditingService as dt, ViewerCollabCursorService as du, ViewerCollaborationSessionService as dv, ViewerCompareService as dw, ViewerCustomShowsService as dx, ViewerDialogsService as dy, ViewerDocumentPropertiesService as dz, AVATAR_COLOR_SWATCHES as e, buildSmartArtNodes as e$, animationFor as e0, animationPresetLabelKey as e1, annotationMapToInkInserts as e2, applyAcceptedDiff as e3, applyAnimationPreset as e4, applyFindReplacements as e5, applyFormatToElement as e6, applyMove as e7, applyResize as e8, asMediaElement as e9, buildDuotoneFilterId as eA, buildEmbeddedFontStyles as eB, buildEquationElement as eC, buildEquationSegment as eD, buildFallbackViewModel as eE, buildFontFaceRule as eF, buildGradientFillCss as eG, buildGridlinesAndLabels as eH, buildHyperlinkPatch as eI, buildInkContainerStyle as eJ, buildInkStrokes as eK, buildLegend as eL, buildLiveInkStrokeView as eM, buildMarkTooltip as eN, buildModel3DContainerStyle as eO, buildModel3DViewModel as eP, buildOleActionModel as eQ, buildOleInfoRows as eR, buildPatternFillCss as eS, buildPieViewModel as eT, buildPrintHtmlDocument as eU, buildPropertiesPatch as eV, buildRadarViewModel as eW, buildRegionMapViewModel as eX, buildSaveSlides as eY, buildShareUrl as eZ, buildSmartArtInsertElement as e_, assignUserColor as ea, attachShowVisibilityPause as eb, attachTouchGestures as ec, axisTickValues as ed, beginDrawingNodeEdit as ee, beginNodeEdit as ef, bevelSizePatch as eg, boolFromEvent as eh, bringForward as ei, bringToFront as ej, buildBarActions as ek, buildBroadcastConfig as el, buildBroadcastViewerUrl as em, buildCategoryLabels as en, buildCellParagraphs as eo, buildChartViewModel as ep, buildChatLogExport as eq, buildChatLogMarkdown as er, buildChromeStyle as es, buildClearHyperlinkPatch as et, buildClickGroups as eu, buildColStyles as ev, buildCollaborationConfig as ew, buildComboViewModel as ex, buildCssGradientFromShapeStyle as ey, buildDuotoneFilter as ez, AXIS_LABEL_COLOR as f, computePieSlices as f$, buildStockViewModel as f0, buildSurfaceViewModel as f1, buildTableViewModel as f2, buildTreemapViewModel as f3, buildTrimFragment as f4, buildWaterfallViewModel as f5, buildZeroLine as f6, buildZoomContainerStyle as f7, buildZoomViewModel as f8, bulletIndentPx as f9, cn as fA, collectAccessibilityIssues as fB, collectElementText as fC, collectSlideText as fD, collectStoredChats as fE, collectUsedFontFamilies as fF, columnWidthStyle as fG, commitNodeText as fH, computeAlign as fI, computeAxisTitlePrimitives as fJ, computeBarRects as fK, computeBubbleRadius as fL, computeCornerHandle as fM, computeDistribute as fN, computeDrawingViewBox as fO, computeErrorBarPrimitives as fP, computeFocusTargets as fQ, computeGridSpacingPx as fR, computeHandleBoxes as fS, computeHandoutLayout as fT, computeIsMobile as fU, computeIsTablet as fV, computeLinePoints as fW, computeLinearRegression as fX, computePageCount as fY, computePieLayout as fZ, computePieSlicePath as f_, canAddTopLevelNode as fa, canEditSmartArtNodes as fb, canGroupSelection as fc, canRemoveTopLevelNode as fd, canSetStrokeWidth as fe, canStartBroadcast as ff, canStartShare as fg, canUngroupSelection as fh, canUseClipboard as fi, captionDisplayText as fj, cellRunStyle as fk, cellStyleToStyleMap as fl, cellTdStyle as fm, changeCountLabel as fn, changeIcon as fo, characterSpacingPatch as fp, chartPreserveAspectRatio as fq, checkFontAvailable as fr, clampCursorPosition as fs, clampGifDimensions as ft, clampIndex as fu, clampNotesFontSize as fv, clampScale as fw, clampStep as fx, clearAllLocalViewerData as fy, clearAudienceContent as fz, AccessibilityPanelComponent as g, fitZoom as g$, computePlotLayout as g0, computeRSquared as g1, computeRadarPoints as g2, computeResizeHandleBoxes as g3, computeRotateHandleBox as g4, computeScatterDots as g5, computeScatterXDomain as g6, computeSelectionBoxes as g7, computeSingleSelected as g8, computeSlideIndices as g9, describeSmartArtBounds as gA, disableGlowPatch as gB, disableInnerShadowPatch as gC, disableOuterShadowPatch as gD, disableReflectionPatch as gE, disableSoftEdgePatch as gF, duplicateElementById as gG, durationOf as gH, effectsStateOf as gI, enableGlowPatch as gJ, enableInnerShadowPatch as gK, enableOuterShadowPatch as gL, enableReflectionPatch as gM, enableSoftEdgePatch as gN, encodeGif as gO, endShowMediaCleanup as gP, estimatePageCount as gQ, exitPresentationFullscreen as gR, exportAiChatLogs as gS, extractPathPoints as gT, eyedropperAvailable as gU, fillColorOf$1 as gV, findInSlides as gW, findOwningSlideIndex as gX, findSlideIndexByElementId as gY, firstVisibleIndex as gZ, fitPolynomial as g_, computeSnap as ga, computeStackedBarRects as gb, computeStackedValueRange as gc, computeTrendlinePrimitives as gd, computeValueRange as ge, convertOmmlToMathMl as gf, copyFormatFromElement as gg, countAccessibilityIssues as gh, countAnnotationStrokes as gi, createAngularAiBridge as gj, createCustomShow as gk, createSwipeDismissDrag as gl, createWebrtcBundle as gm, createWebsocketBundle as gn, cssObjectToStyleMap as go, currentColorScheme as gp, currentLayout as gq, currentStyle as gr, defaultCssVars as gs, defaultRadius as gt, defaultThemeColors as gu, deleteElementsByIds as gv, deleteVersion as gw, demoteNode as gx, deriveModel3DBlobUrl as gy, derivePresenceList as gz, AccessibilityService as h, insertTableElementColumn as h$, focusTargetChips as h0, fontMimeForFormat as h1, fontSizeOf as h2, forgetSessionDeck as h3, formatAxisValue as h4, formatBytes as h5, formatCursorLabel as h6, formatElapsed as h7, formatFileSize as h8, formatPropertyDate as h9, getSessionTabId as hA, getShapeFillStrokeStyle as hB, getSlideBackgroundStyle as hC, getSlideTransitionAnimations as hD, getSmartArtNodeBounds as hE, getSpeechRecognitionCtor as hF, getTextBlockStyle as hG, getTextWarp as hH, getTouchDistance as hI, getWarpCategory as hJ, getWarpPath as hK, gradientStateFromStyle as hL, gradientStateOf as hM, gradientStatePatch as hN, gradientStopColorCommitPatch as hO, gridColumns as hP, groupIssuesBySeverity as hQ, hasAnimation as hR, hasCopyableFormat as hS, hasExistingLink as hT, hasExitedFullscreen as hU, hasGradientFill as hV, hasPressureVariation as hW, hasVisibleSlideAfter as hX, headerLabel as hY, imageDimensions as hZ, inkViewBox as h_, formatTime as ha, fpsToFrameIntervalMs as hb, generateBroadcastRoomId as hc, generateCommentId as hd, generateCustomShowId as he, generatePressureCircles as hf, generateTicks as hg, getClrChangeParams as hh, getContainerStyle as hi, getDuotoneFilterDef as hj, getEffectSoundAsset as hk, getEffectSoundState as hl, getImageSrc as hm, getLocalStorageUsageSummary as hn, getOleAriaLabel as ho, getOleBadgeLabel as hp, getOleDisplayName as hq, getOleDownloadFileName as hr, getOleTypeColor as hs, getOleTypeLabel as ht, getPasswordStrength as hu, getPatternSvg as hv, getPlaceholderStyle as hw, getVersions as hx, getResolvedShapeClipPath as hy, getResolvedShapeClipPathFor as hz, AccessibilityTextPanelComponent as i, normalizeFontFormat as i$, insertTableElementRow as i0, interpolateWidth as i1, isAudienceTab as i2, isBold as i3, isBrowserOpenableMime as i4, isChildNode as i5, isElementInteractive as i6, isInjectableUrl as i7, isItalic as i8, isLegacyBinaryPresentation as i9, mergeCaptionResults as iA, mergeDown as iB, mergeRight as iC, mergeSelection as iD, mergeTablesDirective as iE, moveElementBy as iF, moveNodeDown as iG, moveNodeUp as iH, msToFrameDelayCs as iI, narrowToCircle as iJ, narrowToPolygon as iK, narrowToRect as iL, newChartElement as iM, newEquationElement as iN, newPresetShapeElement as iO, newShapeElement as iP, newSmartArtElement as iQ, newTableElement as iR, newTextElement as iS, nextVisibleIndex as iT, nodeBold as iU, nodeEditBox as iV, nodeFillColor as iW, nodeFontColor as iX, nodeIdFromKey as iY, nodeItalic as iZ, nodeStyle as i_, isPpactionUrl as ia, isPresenterMessage as ib, isSigned as ic, isSupportedPresentationFile as id, isTextElement as ie, isTwoTableFocus as ig, isUnderline as ih, isUrlSafe as ii, isValidRoomId as ij, isViewportBackgroundPressTarget as ik, isZoomActivationKey as il, issueTrackKey as im, issueTypeLabel as io, keyToLabel as ip, lastVisibleIndex as iq, latexToMathml as ir, layoutConnectorPaints as is, layoutNodeLabels as it, linePointsToSvgString as iu, lineSpacingPatch as iv, loadAudienceContent as iw, loadSessionDeck as ix, mediaFallbackFor as iy, mediaSurfaceFor as iz, AccountPageComponent as j, resolveOleType as j$, normalizeSlidesPerPage as j0, normalizeValue as j1, numFromEvent as j2, ommlToMathml as j3, ooxmlDashToCssBorderStyle as j4, openNativeEyeDropper as j5, overallStatus as j6, paletteColor as j7, parseAudienceNonce as j8, parseNodeTextarea as j9, radarRingPoints as jA, readAsDataUrl as jB, recordWebm as jC, registerCrossSlideAudio as jD, rememberSessionDeck as jE, removeAnimation as jF, removeCategory as jG, removeTableElementColumn as jH, removeCommentFromList as jI, removeElementAnimation as jJ, removeGradientStopPatch as jK, removeNode as jL, removeTableElementRow as jM, removeSeries as jN, renderToCanvas as jO, reorderAnimationDown as jP, reorderAnimationUp as jQ, replaceInSlides as jR, replaceMatch as jS, requestPresentationFullscreen as jT, resizeElement as jU, resolveCaptionTracks as jV, resolveChartKind as jW, resolveFontVariant as jX, resolveHyperlinkHref as jY, resolveInteractiveElementId as jZ, resolveMediaSrc as j_, partitionSlides as ja, patchChartData as jb, patchChartStyle as jc, patchTableData as jd, patchTextStyle as je, patternPresetOptions as jf, pendingElementStyles as jg, pickColorByClickFallback as jh, pickFile as ji, pickSupportedMimeType as jj, planGifFrames as jk, planVideoSegments as jl, pointFromPointerEvent as jm, pointsToSvgPathD as jn, presenceToCursors as jo, presentationBaseName as jp, presentationStageStyle as jq, presenterTimerProgress as jr, presetByLayout as js, presetsForCategory as jt, pressuresToWidths as ju, prevVisibleIndex as jv, projectDrawingShapes as jw, promoteNode as jx, provideViewerTheme as jy, radarAngle as jz, ActionSettingsPanelComponent as k, setRepeatMode as k$, resolveParagraphBullet as k0, resolvePresenterNotes as k1, resolveProfileInitial as k2, resolveRegionCode as k3, resolveRibbonCanGroup as k4, resolveSlideAutoAdvanceMs as k5, resolvePalette as k6, resolveThemeCatalogEntry as k7, resolveTransitionDuration as k8, restoreSessionDeck as k9, setAfterAnimationColor as kA, setAnimationEmphasis as kB, setAnimationEntrance as kC, setAnimationExit as kD, setAxis as kE, setAxisLogScale as kF, setAxisTitleStyle as kG, setCategoryLabel as kH, setCellText as kI, setColorScheme as kJ, setDataLabels as kK, setDataPointExplosion as kL, setDataPointFill as kM, setDataPointLabel as kN, setDataPointMarker as kO, setDelay as kP, setDirection as kQ, setDuration as kR, setEffectSound as kS, setEffectStockSound as kT, setElementPosition as kU, setGridlineStyle as kV, setLayout as kW, setLegend as kX, setNodeStyle as kY, setNodeText as kZ, setRepeatCount as k_, revealedElementStyles as ka, routeOrthogonalConnector as kb, rowStyle as kc, rulerDragToGuidePosition as kd, rulerHighlight as ke, rulerStripTicks as kf, sampleColorFromSlide as kg, sanitizeColor as kh, sanitizeSlideIndex as ki, sanitizeUserName as kj, saveViewerProfile as kk, savedPresentationFileName as kl, scanAvailableFonts as km, searchSlides as kn, seedBroadcastFields as ko, seedHyperlinkDraft as kp, seedPropertiesDraft as kq, seedShareFields as kr, segmentFrameCount as ks, selectValue$3 as kt, sendBackward as ku, sendToBack as kv, sequentialColorScale as kw, serializeWriteBack as kx, seriesColor as ky, setAfterAnimation as kz, AdvancedChartEditorComponent as l, updateOuterShadowPatch as l$, setSequence as l0, setSeriesChartType as l1, setSeriesColor as l2, setSeriesErrorBars as l3, setSeriesMarker as l4, setSeriesName as l5, setSeriesTrendline as l6, setSeriesValue as l7, setStyle as l8, setTimingCurve as l9, strokeToInkElement as lA, strokeWidthOf as lB, styleShadowFilter as lC, surfaceColor as lD, textAdvancedPatch as lE, textAdvancedStateFromStyle as lF, textAdvancedStateOf as lG, textColorOf as lH, textDirectionPatch as lI, textFontSizePatch as lJ, textStyleOf as lK, textStylePatch as lL, themeStyle as lM, themeToCssVars as lN, thumbnailHeight as lO, thumbnailZoom as lP, toggleCommentResolvedInList as lQ, toggleNodeBold as lR, toggleNodeItalic as lS, toggleSheet as lT, topLevelNodeCount as lU, transformSelectedTextCase as lV, translationsEn as lW, updateElementById as lX, updateGlowPatch as lY, updateGradientStopPatch as lZ, updateInnerShadowPatch as l_, setTitle as la, setTrigger as lb, setTriggerShapeId as lc, shapeStylePatch$1 as ld, sheetAfterNavigate as le, shouldBlockClickAdvance as lf, shouldUseSvgWarp as lg, showDirectionPicker as lh, showsTemplateAffordance as li, signatureCountLabel as lj, signatureKey as lk, signatureTimestamp as ll, signerName as lm, statusLabel as ln, slideNumberOf as lo, slidesWithReappliedLayout as lp, smartArtNodes as lq, paletteColour as lr, snapToGridStep as ls, splitCursorCell as lt, splitMergedCell as lu, statusKind as lv, statusLabel$1 as lw, storeAudienceContent as lx, stringFromEvent$5 as ly, strokeColorOf as lz, AiChangeOverlayComponent as m, updateReflectionPatch as m0, vAlignPatch as m1, validatePassword as m2, validatePrintSettings as m3, validateRoomId as m4, valueToY as m5, vermilionDarkColors as m6, vermilionDarkTheme as m7, vermilionLightColors as m8, vermilionLightTheme as m9, vermilionRadius as ma, waypointsToPathD as mb, withManualLayouts as mc, worstStatus as md, zoomTargetSlideIndex as me, AiChatPanelComponent as n, AiChatService as o, AiComposerComponent as p, AiFocusBarComponent as q, AiFocusHighlightOverlayComponent as r, AiHistoryMenuComponent as s, toChatSummary as t, AiHistoryService as u, AiMessageListComponent as v, AiPanelStore as w, AiProposalCardComponent as x, AiSettingsSectionComponent as y, AiToolCallCardComponent as z };
182143
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-DMCiVwQO.mjs.map
182571
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CK_kxJxU.mjs.map