pptx-angular-viewer 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-BxlsOXEi.mjs → pptx-angular-viewer-chat-history-idb-BHSiNfjU.mjs} +2 -2
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-BxlsOXEi.mjs.map → pptx-angular-viewer-chat-history-idb-BHSiNfjU.mjs.map} +1 -1
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-3iTbE0x6.mjs → pptx-angular-viewer-pptx-angular-viewer-BzS7I0F9.mjs} +2418 -98
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-3iTbE0x6.mjs.map → pptx-angular-viewer-pptx-angular-viewer-BzS7I0F9.mjs.map} +1 -1
- package/fesm2022/pptx-angular-viewer.mjs +1 -1
- package/package.json +3 -3
- package/types/pptx-angular-viewer.d.ts +292 -7
- package/types/pptx-angular-viewer.d.ts.map +1 -1
|
@@ -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 } 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, stripXmlOrderSuffix, orderedXmlKey, chartDataChangeType, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, formatAutoNumberMarker, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, evaluateGuides, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, parseDataUrlToBytes, deobfuscateFont, detectFontFormat, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, resolveThemeColorRef, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, 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, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, 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, stripXmlOrderSuffix, orderedXmlKey, flattenChartUserShapes, chartDataChangeType, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, formatAutoNumberMarker, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, evaluateGuides, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, parseDataUrlToBytes, deobfuscateFont, detectFontFormat, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, resolveThemeColorRef, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, 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, 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 DOMPurify from 'dompurify';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import * as mcp from 'pptx-viewer-mcp';
|
|
@@ -17530,6 +17530,73 @@ function buildTreemapViewModel(element, chartData, categoryLabels) {
|
|
|
17530
17530
|
};
|
|
17531
17531
|
}
|
|
17532
17532
|
|
|
17533
|
+
/**
|
|
17534
|
+
* Resolve `chartData.titleRuns` into per-run SVG `<tspan>` descriptors, each
|
|
17535
|
+
* run's own bold/italic/size/colour falling back to the title's cascade
|
|
17536
|
+
* (`resolveChartTitleTextStyle`) for whatever it does not override.
|
|
17537
|
+
*
|
|
17538
|
+
* Returns `undefined` when the title has no typed runs at all (an auto/plain
|
|
17539
|
+
* title, or one authored as a linked-cell reference), so a binding should
|
|
17540
|
+
* keep rendering the flat `vm.title` in `vm.titleStyle` unchanged. A single
|
|
17541
|
+
* run still resolves to a one-element array: this lets a per-run override
|
|
17542
|
+
* (e.g. italic on the title's only run) render even when
|
|
17543
|
+
* `resolveChartTitleTextStyle`'s coarser `chartData.style.titleFont*` cascade
|
|
17544
|
+
* does not carry it.
|
|
17545
|
+
*/
|
|
17546
|
+
function resolveChartTitleRunSpans(chartData) {
|
|
17547
|
+
const runs = chartData?.titleRuns;
|
|
17548
|
+
if (!runs || runs.length === 0) {
|
|
17549
|
+
return undefined;
|
|
17550
|
+
}
|
|
17551
|
+
const base = resolveChartTitleTextStyle(chartData);
|
|
17552
|
+
return runs.map((run) => ({
|
|
17553
|
+
text: run.text,
|
|
17554
|
+
fontSize: run.fontSize !== undefined ? chartFontPx(run.fontSize) : base.fontSize,
|
|
17555
|
+
fontWeight: run.bold !== undefined ? (run.bold ? 700 : 400) : base.fontWeight,
|
|
17556
|
+
...(run.italic ? { fontStyle: 'italic' } : {}),
|
|
17557
|
+
fill: run.color ?? base.fill,
|
|
17558
|
+
...(base.fontFamily ? { fontFamily: base.fontFamily } : {}),
|
|
17559
|
+
}));
|
|
17560
|
+
}
|
|
17561
|
+
/**
|
|
17562
|
+
* The dominant style among `runs`: the longest run's (by text length; ties
|
|
17563
|
+
* keep the first), since that is the style covering most of the visible
|
|
17564
|
+
* title text.
|
|
17565
|
+
*/
|
|
17566
|
+
function dominantRunStyle(runs) {
|
|
17567
|
+
let best = runs[0];
|
|
17568
|
+
for (const run of runs.slice(1)) {
|
|
17569
|
+
if (run.text.length > best.text.length) {
|
|
17570
|
+
best = run;
|
|
17571
|
+
}
|
|
17572
|
+
}
|
|
17573
|
+
const { bold, italic, fontSize, color } = best;
|
|
17574
|
+
return {
|
|
17575
|
+
...(bold !== undefined ? { bold } : {}),
|
|
17576
|
+
...(italic !== undefined ? { italic } : {}),
|
|
17577
|
+
...(fontSize !== undefined ? { fontSize } : {}),
|
|
17578
|
+
...(color !== undefined ? { color } : {}),
|
|
17579
|
+
};
|
|
17580
|
+
}
|
|
17581
|
+
/**
|
|
17582
|
+
* Compute the `{ title, titleRuns }` patch for an inspector's flat title-text
|
|
17583
|
+
* field being edited to `newText`. Every binding's chart title input should
|
|
17584
|
+
* call this instead of patching `title` alone.
|
|
17585
|
+
*
|
|
17586
|
+
* A title with zero or one run just gets the new flat text (`titleRuns`
|
|
17587
|
+
* untouched, letting core's single-run patch path preserve that run's full
|
|
17588
|
+
* authored formatting). A title with two or more runs collapses to ONE run
|
|
17589
|
+
* carrying `newText` in the dominant style, so the edit does not leave a
|
|
17590
|
+
* second, now-stale run's text trailing the new title.
|
|
17591
|
+
*/
|
|
17592
|
+
function collapseChartTitleRunsForEdit(chartData, newText) {
|
|
17593
|
+
const runs = chartData?.titleRuns;
|
|
17594
|
+
if (!runs || runs.length <= 1) {
|
|
17595
|
+
return { title: newText };
|
|
17596
|
+
}
|
|
17597
|
+
return { title: newText, titleRuns: [{ ...dominantRunStyle(runs), text: newText }] };
|
|
17598
|
+
}
|
|
17599
|
+
|
|
17533
17600
|
/**
|
|
17534
17601
|
* Chart drawing-overlay projector (`c:userShapes`).
|
|
17535
17602
|
*
|
|
@@ -17540,6 +17607,11 @@ function buildTreemapViewModel(element, chartData, categoryLabels) {
|
|
|
17540
17607
|
* `absSizeAnchor` extents are EMU converted to pixels. Rendered last so the
|
|
17541
17608
|
* overlay sits above the data marks.
|
|
17542
17609
|
*
|
|
17610
|
+
* A `grpSp` entry (grouped annotation shapes with their own nested
|
|
17611
|
+
* transform) is expanded into positioned leaves via core's
|
|
17612
|
+
* `flattenChartUserShapes` before projecting, so this module never has to
|
|
17613
|
+
* know about groups itself.
|
|
17614
|
+
*
|
|
17543
17615
|
* @module chart-user-shape-overlay
|
|
17544
17616
|
*/
|
|
17545
17617
|
/** EMU per CSS pixel at 96 DPI, mirroring core's `EMU_PER_PIXEL`. */
|
|
@@ -17637,7 +17709,8 @@ function buildChartUserShapeOverlay(userShapes, svgWidth, svgHeight) {
|
|
|
17637
17709
|
if (!userShapes || userShapes.length === 0) {
|
|
17638
17710
|
return [];
|
|
17639
17711
|
}
|
|
17640
|
-
|
|
17712
|
+
const leaves = flattenChartUserShapes(userShapes);
|
|
17713
|
+
return leaves.flatMap((shape) => projectShape(shape, svgWidth, svgHeight));
|
|
17641
17714
|
}
|
|
17642
17715
|
|
|
17643
17716
|
/**
|
|
@@ -19518,11 +19591,13 @@ function withLegendEntries(vm, chartData) {
|
|
|
19518
19591
|
* declares `<a:noFill/>` gets `areaFill: undefined` and no rect at all.
|
|
19519
19592
|
*/
|
|
19520
19593
|
function withChartAreaFill(vm, chartData) {
|
|
19594
|
+
const titleRunSpans = resolveChartTitleRunSpans(chartData);
|
|
19521
19595
|
return {
|
|
19522
19596
|
...vm,
|
|
19523
19597
|
areaFill: chartAreaFill(chartData),
|
|
19524
19598
|
areaRadius: chartAreaCornerRadius(chartData),
|
|
19525
19599
|
titleStyle: resolveChartTitleTextStyle(chartData),
|
|
19600
|
+
...(titleRunSpans ? { titleRunSpans } : {}),
|
|
19526
19601
|
plotFill: plotAreaFill(chartData),
|
|
19527
19602
|
};
|
|
19528
19603
|
}
|
|
@@ -20786,6 +20861,127 @@ function setChartCellValue(data, seriesIndex, categoryIndex, raw) {
|
|
|
20786
20861
|
return chartDataUpdatePoint(data, seriesIndex, categoryIndex, value);
|
|
20787
20862
|
}
|
|
20788
20863
|
|
|
20864
|
+
const TWO_PI = Math.PI * 2;
|
|
20865
|
+
/** Keep the dragged span strictly inside (0, 2*PI) so the share never hits 0 or 1. */
|
|
20866
|
+
const ANGLE_EPSILON = TWO_PI * 0.001;
|
|
20867
|
+
/**
|
|
20868
|
+
* Resolve the drag geometry for series 0's slice at `pointIndex`, or `null`
|
|
20869
|
+
* when `chartData` is not a pie/doughnut, has no series, or the index is out
|
|
20870
|
+
* of range. `element` is the chart's frame box (EMU-agnostic width/height, the
|
|
20871
|
+
* same units `PptxElement.width/height` and `computePieLayout` use).
|
|
20872
|
+
*/
|
|
20873
|
+
function buildPieDragGeometry(element, chartData, pointIndex) {
|
|
20874
|
+
if (chartData.chartType !== 'pie' && chartData.chartType !== 'doughnut') {
|
|
20875
|
+
return null;
|
|
20876
|
+
}
|
|
20877
|
+
const series = chartData.series[0];
|
|
20878
|
+
if (!series || pointIndex < 0 || pointIndex >= series.values.length) {
|
|
20879
|
+
return null;
|
|
20880
|
+
}
|
|
20881
|
+
const isDoughnut = chartData.chartType === 'doughnut', { cx, cy } = computePieLayout(element.width, element.height, chartData, isDoughnut),
|
|
20882
|
+
// Mirrors buildPieViewModel's own startAngle line exactly (chart-view-model-pie.ts).
|
|
20883
|
+
startAngle = -Math.PI / 2 + ((chartData.firstSliceAngle ?? 0) * Math.PI) / 180;
|
|
20884
|
+
return { cx, cy, values: series.values, pointIndex, startAngle };
|
|
20885
|
+
}
|
|
20886
|
+
/**
|
|
20887
|
+
* New value for the dragged slice given the pointer's (view-box) position.
|
|
20888
|
+
* The slice's leading edge stays put; the span from there to the pointer's
|
|
20889
|
+
* angle becomes the slice's new share of the series total, and
|
|
20890
|
+
* {@link shareToValue} converts that share back to an absolute value holding
|
|
20891
|
+
* every other (unchanged) slice's value fixed.
|
|
20892
|
+
*/
|
|
20893
|
+
function resolvePieDragValue(geometry, pointerX, pointerY) {
|
|
20894
|
+
const { cx, cy, values, pointIndex, startAngle } = geometry, total = values.reduce((sum, v) => sum + Math.abs(v), 0) || 1, before = values.slice(0, pointIndex).reduce((sum, v) => sum + Math.abs(v), 0), leadingAngle = startAngle + (before / total) * TWO_PI, pointerAngle = Math.atan2(pointerY - cy, pointerX - cx), rawSpan = ((pointerAngle - leadingAngle) % TWO_PI) + TWO_PI, span = Math.min(Math.max(rawSpan % TWO_PI, ANGLE_EPSILON), TWO_PI - ANGLE_EPSILON), share = span / TWO_PI, own = values[pointIndex] ?? 0, sign = own < 0 ? -1 : 1, others = total - Math.abs(own), absValue = shareToValue(share, others), range = {
|
|
20895
|
+
min: 0,
|
|
20896
|
+
max: Math.max(total, absValue, 1),
|
|
20897
|
+
span: Math.max(total, absValue, 1),
|
|
20898
|
+
};
|
|
20899
|
+
return roundDragValue(sign * absValue, range);
|
|
20900
|
+
}
|
|
20901
|
+
|
|
20902
|
+
/**
|
|
20903
|
+
* Resolve the drag geometry for `pointIndex`'s vertex, or `null` when
|
|
20904
|
+
* `chartData` is not a radar chart or the index is out of range. Mirrors
|
|
20905
|
+
* `buildRadarViewModel`'s own cx/cy/radius/maxVal derivation exactly
|
|
20906
|
+
* (chart-view-model-radar.ts) so the drag target never drifts from what is
|
|
20907
|
+
* actually drawn.
|
|
20908
|
+
*/
|
|
20909
|
+
function buildRadarDragGeometry(element, chartData, categoryLabels, pointIndex) {
|
|
20910
|
+
if (chartData.chartType !== 'radar') {
|
|
20911
|
+
return null;
|
|
20912
|
+
}
|
|
20913
|
+
const catCount = Math.max(categoryLabels.length, 1);
|
|
20914
|
+
if (pointIndex < 0 || pointIndex >= catCount) {
|
|
20915
|
+
return null;
|
|
20916
|
+
}
|
|
20917
|
+
const layout = computePlotLayout(element.width, element.height, chartData, false), cx = layout.plotLeft + layout.plotWidth / 2, cy = layout.plotTop + layout.plotHeight / 2, radius = Math.max(Math.min(layout.plotWidth, layout.plotHeight) / 2 - 4, 1), maxVal = Math.max(1, ...chartData.series.flatMap((s) => s.values.map((v) => Math.abs(v)))), angle = radarAngle(pointIndex, catCount);
|
|
20918
|
+
return { cx, cy, radius, maxVal, angle };
|
|
20919
|
+
}
|
|
20920
|
+
/**
|
|
20921
|
+
* New value for the dragged vertex given the pointer's (view-box) position:
|
|
20922
|
+
* the pointer vector from the centre is projected onto the spoke direction
|
|
20923
|
+
* (perpendicular drift is ignored, matching "radial drag along the category
|
|
20924
|
+
* spoke"), clamped to non-negative, then scaled back from ring radius to
|
|
20925
|
+
* value via the same `radius / maxVal` ratio the renderer draws with.
|
|
20926
|
+
*/
|
|
20927
|
+
function resolveRadarDragValue(geometry, pointerX, pointerY) {
|
|
20928
|
+
const { cx, cy, radius, maxVal, angle } = geometry, dx = pointerX - cx, dy = pointerY - cy, radial = Math.max(dx * Math.cos(angle) + dy * Math.sin(angle), 0), value = (radial / radius) * maxVal, range = {
|
|
20929
|
+
min: 0,
|
|
20930
|
+
max: Math.max(maxVal, value, 1),
|
|
20931
|
+
span: Math.max(maxVal, value, 1),
|
|
20932
|
+
};
|
|
20933
|
+
return roundDragValue(value, range);
|
|
20934
|
+
}
|
|
20935
|
+
|
|
20936
|
+
/**
|
|
20937
|
+
* Resolve the drag geometry for one (seriesIndex, pointIndex) stacked
|
|
20938
|
+
* segment, or `null` when the chart is not stacked/percentStacked, the series
|
|
20939
|
+
* has no values, or the point is out of range.
|
|
20940
|
+
*/
|
|
20941
|
+
function buildStackedDragGeometry(element, chartData, seriesIndex, pointIndex) {
|
|
20942
|
+
const grouping = chartData.grouping;
|
|
20943
|
+
if (grouping !== 'stacked' && grouping !== 'percentStacked') {
|
|
20944
|
+
return null;
|
|
20945
|
+
}
|
|
20946
|
+
const seriesValues = chartData.series.map((s) => s.values), draggedValues = seriesValues[seriesIndex];
|
|
20947
|
+
if (!draggedValues || pointIndex < 0 || pointIndex >= draggedValues.length) {
|
|
20948
|
+
return null;
|
|
20949
|
+
}
|
|
20950
|
+
const percent = grouping === 'percentStacked', catCount = Math.max(chartData.categories.length, ...seriesValues.map((values) => values.length), pointIndex + 1), plots = computeStackedSeriesPlots(seriesValues, catCount, percent), baseValue = plots[seriesIndex]?.base[pointIndex] ?? 0, otherAbsSum = seriesValues.reduce((sum, values, si) => (si === seriesIndex ? sum : sum + Math.abs(values[pointIndex] ?? 0)), 0), range = percent
|
|
20951
|
+
? { min: 0, max: 100, span: 100 }
|
|
20952
|
+
: computeStackedValueRange(chartData.series, catCount), layoutOpts = computeLayoutOptions(chartData.axes, chartData.dataTable, chartData.series.length), layout = computePlotLayout(element.width, element.height, chartData, true, layoutOpts);
|
|
20953
|
+
return {
|
|
20954
|
+
range,
|
|
20955
|
+
plotTop: layout.plotTop,
|
|
20956
|
+
plotBottom: layout.plotBottom,
|
|
20957
|
+
baseValue,
|
|
20958
|
+
otherAbsSum,
|
|
20959
|
+
percent,
|
|
20960
|
+
};
|
|
20961
|
+
}
|
|
20962
|
+
/**
|
|
20963
|
+
* New value for the dragged series at this category given the pointer's Y
|
|
20964
|
+
* (view-box units). The pointer projects to a cumulative value/percent at the
|
|
20965
|
+
* segment's top edge; subtracting the fixed base below it gives the dragged
|
|
20966
|
+
* series' own new share. A plain stacked chart uses that directly (the other
|
|
20967
|
+
* series' absolute values are untouched, so the category total simply grows
|
|
20968
|
+
* or shrinks); percentStacked instead treats it as a percentage SHARE and
|
|
20969
|
+
* converts it back to an absolute value via {@link shareToValue}, holding
|
|
20970
|
+
* every other series' value fixed (matching the pie slice renormalisation).
|
|
20971
|
+
*/
|
|
20972
|
+
function resolveStackedDragValue(geometry, pointerY) {
|
|
20973
|
+
const { range, plotTop, plotBottom, baseValue, otherAbsSum, percent } = geometry, pointerScalar = valueFromY(pointerY, range, plotTop, plotBottom), delta = pointerScalar - baseValue;
|
|
20974
|
+
if (!percent) {
|
|
20975
|
+
return roundDragValue(delta, range);
|
|
20976
|
+
}
|
|
20977
|
+
const sign = delta < 0 ? -1 : 1, absValue = shareToValue(Math.abs(delta) / 100, otherAbsSum), valueRange = {
|
|
20978
|
+
min: 0,
|
|
20979
|
+
max: Math.max(otherAbsSum, absValue, 1),
|
|
20980
|
+
span: Math.max(otherAbsSum, absValue, 1),
|
|
20981
|
+
};
|
|
20982
|
+
return roundDragValue(sign * absValue, valueRange);
|
|
20983
|
+
}
|
|
20984
|
+
|
|
20789
20985
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
20790
20986
|
// DOM data-attribute bridge
|
|
20791
20987
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -20886,6 +21082,23 @@ function roundDragValue(value, range) {
|
|
|
20886
21082
|
// Snap away float noise from the multiplication (e.g. 0.30000000000000004).
|
|
20887
21083
|
return Number.parseFloat(rounded.toPrecision(12));
|
|
20888
21084
|
}
|
|
21085
|
+
/**
|
|
21086
|
+
* Convert a target SHARE (0..1, exclusive) of a whole back to an absolute
|
|
21087
|
+
* value, holding every other part's absolute value (`otherAbsSum`) fixed:
|
|
21088
|
+
* `share = value / (value + otherAbsSum)` solved for `value`. Used by both a
|
|
21089
|
+
* dragged pie/doughnut slice's angle share and a dragged percentStacked
|
|
21090
|
+
* segment's percent share, so the two renormalise identically. `share` is
|
|
21091
|
+
* clamped short of 1 so a lone part (no others to renormalise against) still
|
|
21092
|
+
* returns a finite, monotonically increasing value instead of Infinity.
|
|
21093
|
+
*/
|
|
21094
|
+
function shareToValue(share, otherAbsSum) {
|
|
21095
|
+
const clamped = Math.min(Math.max(share, 0), 0.999999);
|
|
21096
|
+
if (clamped <= 0) {
|
|
21097
|
+
return 0;
|
|
21098
|
+
}
|
|
21099
|
+
const ratio = clamped / (1 - clamped);
|
|
21100
|
+
return otherAbsSum > 0 ? ratio * otherAbsSum : ratio;
|
|
21101
|
+
}
|
|
20889
21102
|
/** The value range a series maps against (secondary when axis-mapped there). */
|
|
20890
21103
|
function rangeForSeries(drag, seriesIndex) {
|
|
20891
21104
|
const useSecondary = drag.secondaryRange !== undefined &&
|
|
@@ -20937,10 +21150,53 @@ function withChartTitle(chartData, title) {
|
|
|
20937
21150
|
const trimmed = title.trim();
|
|
20938
21151
|
return {
|
|
20939
21152
|
...chartData,
|
|
20940
|
-
title
|
|
21153
|
+
// A multi-run title collapses to one run in its dominant style so this
|
|
21154
|
+
// edit does not leave another, now-stale run's text trailing the new
|
|
21155
|
+
// title; see `collapseChartTitleRunsForEdit`'s doc.
|
|
21156
|
+
...collapseChartTitleRunsForEdit(chartData, trimmed),
|
|
20941
21157
|
style: { ...chartData.style, hasTitle: trimmed.length > 0 },
|
|
20942
21158
|
};
|
|
20943
21159
|
}
|
|
21160
|
+
/**
|
|
21161
|
+
* Resolve a mark drag's geometry for the given chart kind and part, or `null`
|
|
21162
|
+
* when that kind/part combination has no drag meaning (e.g. a clustered bar,
|
|
21163
|
+
* which uses `ChartValueDrag`/`dragValueForPart` instead).
|
|
21164
|
+
*/
|
|
21165
|
+
function buildChartMarkDragGeometry(params) {
|
|
21166
|
+
const { kind, element, chartData, categoryLabels, seriesIndex, pointIndex } = params;
|
|
21167
|
+
if (kind === 'pie' || kind === 'doughnut') {
|
|
21168
|
+
const geometry = buildPieDragGeometry(element, chartData, pointIndex);
|
|
21169
|
+
return geometry ? { kind: 'pie', ...geometry } : null;
|
|
21170
|
+
}
|
|
21171
|
+
if (kind === 'radar') {
|
|
21172
|
+
const geometry = buildRadarDragGeometry(element, chartData, categoryLabels, pointIndex);
|
|
21173
|
+
return geometry ? { kind: 'radar', ...geometry } : null;
|
|
21174
|
+
}
|
|
21175
|
+
if (kind === 'bar' || kind === 'line' || kind === 'area') {
|
|
21176
|
+
const geometry = buildStackedDragGeometry(element, chartData, seriesIndex, pointIndex);
|
|
21177
|
+
return geometry ? { kind: 'stackedSegment', ...geometry } : null;
|
|
21178
|
+
}
|
|
21179
|
+
return null;
|
|
21180
|
+
}
|
|
21181
|
+
/**
|
|
21182
|
+
* New value for a dragged mark, dispatched by the geometry's own `kind`. This
|
|
21183
|
+
* is the single entry point every binding's pointer handler calls; each kind's
|
|
21184
|
+
* actual math lives in its own `chart-interaction-*.ts` sibling.
|
|
21185
|
+
*/
|
|
21186
|
+
function resolveChartDragValue(geometry, pointer) {
|
|
21187
|
+
switch (geometry.kind) {
|
|
21188
|
+
case 'pie':
|
|
21189
|
+
return resolvePieDragValue(geometry, pointer.x, pointer.y);
|
|
21190
|
+
case 'radar':
|
|
21191
|
+
return resolveRadarDragValue(geometry, pointer.x, pointer.y);
|
|
21192
|
+
case 'stackedSegment':
|
|
21193
|
+
return resolveStackedDragValue(geometry, pointer.y);
|
|
21194
|
+
default: {
|
|
21195
|
+
const exhaustive = geometry;
|
|
21196
|
+
return exhaustive;
|
|
21197
|
+
}
|
|
21198
|
+
}
|
|
21199
|
+
}
|
|
20944
21200
|
|
|
20945
21201
|
/**
|
|
20946
21202
|
* Minimum pointer travel (px) before a mark press becomes a value drag.
|
|
@@ -21184,6 +21440,65 @@ function validateChartUserShapeAnchor(shape) {
|
|
|
21184
21440
|
return undefined;
|
|
21185
21441
|
}
|
|
21186
21442
|
|
|
21443
|
+
/**
|
|
21444
|
+
* Map a client-space pointer position into the chart's SVG view-box units,
|
|
21445
|
+
* given the rendered `<svg>`'s bounding rect.
|
|
21446
|
+
*/
|
|
21447
|
+
function clientPointToViewBox(clientX, clientY, rect, svgWidth, svgHeight) {
|
|
21448
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
21449
|
+
return { x: 0, y: 0 };
|
|
21450
|
+
}
|
|
21451
|
+
return {
|
|
21452
|
+
x: ((clientX - rect.left) / rect.width) * svgWidth,
|
|
21453
|
+
y: ((clientY - rect.top) / rect.height) * svgHeight,
|
|
21454
|
+
};
|
|
21455
|
+
}
|
|
21456
|
+
/**
|
|
21457
|
+
* Start a mark drag, or return `null` when there is no geometry for this part
|
|
21458
|
+
* (not a draggable mark kind, or the press was not on a `dataPoint`).
|
|
21459
|
+
*/
|
|
21460
|
+
function beginChartMarkDrag(params) {
|
|
21461
|
+
const { part, geometry, chartData, svgWidth, svgHeight, clientX, clientY } = params;
|
|
21462
|
+
if (!geometry || part.role !== 'dataPoint' || part.pointIndex === undefined) {
|
|
21463
|
+
return null;
|
|
21464
|
+
}
|
|
21465
|
+
return {
|
|
21466
|
+
part,
|
|
21467
|
+
geometry,
|
|
21468
|
+
svgWidth,
|
|
21469
|
+
svgHeight,
|
|
21470
|
+
baseChartData: chartData,
|
|
21471
|
+
startClientX: clientX,
|
|
21472
|
+
startClientY: clientY,
|
|
21473
|
+
moved: false,
|
|
21474
|
+
lastData: null,
|
|
21475
|
+
};
|
|
21476
|
+
}
|
|
21477
|
+
/**
|
|
21478
|
+
* Advance an in-flight mark drag to the pointer's current client position.
|
|
21479
|
+
*
|
|
21480
|
+
* Returns `null` (leaving `state` untouched) while the press is still inside
|
|
21481
|
+
* the click threshold or `rect` is not measurable. Otherwise MUTATES
|
|
21482
|
+
* `state.moved` / `state.lastData` and returns the step, so the caller can
|
|
21483
|
+
* preview it and commit `state.lastData` once on release.
|
|
21484
|
+
*/
|
|
21485
|
+
function advanceChartMarkDrag(state, clientX, clientY, rect) {
|
|
21486
|
+
if (state.part.pointIndex === undefined) {
|
|
21487
|
+
return null;
|
|
21488
|
+
}
|
|
21489
|
+
const travelled = Math.hypot(clientX - state.startClientX, clientY - state.startClientY);
|
|
21490
|
+
if (!state.moved && travelled < CHART_DRAG_THRESHOLD_PX) {
|
|
21491
|
+
return null;
|
|
21492
|
+
}
|
|
21493
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
21494
|
+
return null;
|
|
21495
|
+
}
|
|
21496
|
+
state.moved = true;
|
|
21497
|
+
const pointer = clientPointToViewBox(clientX, clientY, rect, state.svgWidth, state.svgHeight), value = resolveChartDragValue(state.geometry, pointer), chartData = withChartPointValue(state.baseChartData, state.part.seriesIndex, state.part.pointIndex, value);
|
|
21498
|
+
state.lastData = chartData;
|
|
21499
|
+
return { chartData, value };
|
|
21500
|
+
}
|
|
21501
|
+
|
|
21187
21502
|
/**
|
|
21188
21503
|
* `animation-mask-reveal`: CSS `mask`-based reveal states for the clip family
|
|
21189
21504
|
* of entrance/exit effects (wipe, peek, blinds, split, box, random bars).
|
|
@@ -22993,8 +23308,10 @@ const EXTENDED_ENTR_PRESETS = {
|
|
|
22993
23308
|
* Split) had no dedicated exit keyframe at all before this pass, unlike their
|
|
22994
23309
|
* entrance counterparts; the new `peekOut`/`splitOut` keyframes in
|
|
22995
23310
|
* `animation-keyframes-exit-shapes.ts` reuse the same mask-reveal technique
|
|
22996
|
-
* in reverse. exit.11 and exit.12 are intentionally NOT in this table:
|
|
22997
|
-
*
|
|
23311
|
+
* in reverse. exit.11 and exit.12 are intentionally NOT in this table: both
|
|
23312
|
+
* now have dedicated playback keyframes (`flashOnceOut`, `peekOutDown`)
|
|
23313
|
+
* wired directly in `animation-presets-exit.ts` alongside this pass's other
|
|
23314
|
+
* directly-verified ids, rather than through this extended table.
|
|
22998
23315
|
*/
|
|
22999
23316
|
const EXTENDED_EXIT_PRESETS = {
|
|
23000
23317
|
7: 'flyOutBottom', // Crawl Out
|
|
@@ -23161,10 +23478,21 @@ const ENTR_PRESETS = {
|
|
|
23161
23478
|
*/
|
|
23162
23479
|
/** OOXML exit `p:cTn/@presetId` -> playback effect name. */
|
|
23163
23480
|
const EXIT_PRESETS$1 = {
|
|
23164
|
-
// exit.11 (Flash Once)
|
|
23165
|
-
//
|
|
23166
|
-
//
|
|
23167
|
-
//
|
|
23481
|
+
// exit.11 (Flash Once), verified via COM: `msoAnimEffectFlashOnce` with
|
|
23482
|
+
// `Effect.Exit = True` serializes as presetID 11 with no `@filter`,
|
|
23483
|
+
// matching entr.11's `flashIn`. Plays via its own `flashOnceOut` keyframe
|
|
23484
|
+
// (a `style.visibility` flicker ending hidden) rather than the entrance
|
|
23485
|
+
// keyframe played backwards, since PowerPoint's own authored effect is a
|
|
23486
|
+
// discrete visibility toggle pair, not a smooth opacity ramp.
|
|
23487
|
+
11: 'flashOnceOut',
|
|
23488
|
+
// exit.12 (Peek Out, presetSubtype 4 / bottom edge), verified via COM
|
|
23489
|
+
// (this repo's own PowerShell automation): `AddEffect` with the Peek In
|
|
23490
|
+
// `MsoAnimEffect` constant then `Effect.Exit = True` re-emits
|
|
23491
|
+
// `presetID="12"` with `filter="wipe(down)"`. Named `peekOutDown` (not
|
|
23492
|
+
// `peekOut`) because that name is already bound to exit.16's own
|
|
23493
|
+
// (pre-existing, out-of-scope) "Peek Out" mismatch; see
|
|
23494
|
+
// `animation-keyframes-exit-shapes.ts`'s note on both keyframes.
|
|
23495
|
+
12: 'peekOutDown',
|
|
23168
23496
|
1: 'disappear',
|
|
23169
23497
|
2: 'flyOutBottom',
|
|
23170
23498
|
// exit.6 = Circle, confirmed via COM (`msoAnimEffectCircle` with
|
|
@@ -23335,6 +23663,310 @@ const PRESET_ID_TO_EFFECT = {
|
|
|
23335
23663
|
emph: EMPH_PRESETS,
|
|
23336
23664
|
};
|
|
23337
23665
|
|
|
23666
|
+
/**
|
|
23667
|
+
* `animation-text-style-resolve` - resolves the discrete font-style / colour /
|
|
23668
|
+
* size override PowerPoint's font-style emphasis effects apply to their
|
|
23669
|
+
* target's text: Bold Flash, Bold Reveal, Underline, Brush On Underline,
|
|
23670
|
+
* Font Style / Change Font Style, Change Font Size, and the font-style `p:set`
|
|
23671
|
+
* siblings composed alongside Wave / Grow With Color / Teeter.
|
|
23672
|
+
*
|
|
23673
|
+
* PowerPoint authors these two ways, both already parsed by core:
|
|
23674
|
+
* - A `p:set` discrete (non-interpolated) assignment
|
|
23675
|
+
* ({@link PptxNativeAnimation.setAnimations}, ECMA-376 S19.5.79
|
|
23676
|
+
* CT_TLSetBehavior): the value snaps on once and holds until the effect's
|
|
23677
|
+
* `p:cTn/@fill` says otherwise (Bold Reveal, Underline / Brush On
|
|
23678
|
+
* Underline).
|
|
23679
|
+
* - A generic `p:anim` ramp ({@link PptxNativeAnimation.attributeAnimations},
|
|
23680
|
+
* ECMA-376 S19.5.2 CT_TLAnimateBehavior) whose `p:tavLst` stops are not
|
|
23681
|
+
* numerically interpolatable for a boolean attribute (Bold Flash): only the
|
|
23682
|
+
* LAST stop's value is meaningful, the same "snap at the end" reading
|
|
23683
|
+
* PowerPoint itself gives a discrete `calcMode` ramp.
|
|
23684
|
+
*
|
|
23685
|
+
* Ground truth (COM `AddEffect` + raw OOXML inspection, see
|
|
23686
|
+
* `animation-emphasis-ground-truth-early.ts`): `style.fontWeight` (bold),
|
|
23687
|
+
* `style.fontStyle` (italic), `style.textDecorationUnderline` (underline),
|
|
23688
|
+
* `style.fontSize` (a numeric ramp: this module reads its FIRST/LAST stop
|
|
23689
|
+
* ratio as {@link TextStyleAnimationDescriptor.fontScale}, a relative
|
|
23690
|
+
* multiplier rather than an absolute size, since a shape's runs may not all
|
|
23691
|
+
* share the authored effect's own reference size), and `style.color` (font
|
|
23692
|
+
* colour, distinct from `fillcolor`/`stroke.color`, which the existing
|
|
23693
|
+
* `p:animClr` colour-animation path already owns).
|
|
23694
|
+
*
|
|
23695
|
+
* Deliberately does NOT model a "during" vs "after" phase distinction: the
|
|
23696
|
+
* hold-vs-revert decision this effect's `p:cTn/@fill` makes is already
|
|
23697
|
+
* computed once, correctly, by `animation-fill-repeat.ts`'s
|
|
23698
|
+
* `shouldHoldEndState` (the exact same rule CSS-animation steps already use
|
|
23699
|
+
* to decide whether their final frame persists on cleanup) and surfaced on
|
|
23700
|
+
* {@link import('./animation-timeline-types').TimelineStep.holdEndState}.
|
|
23701
|
+
* `animation-text-style-state.ts` reuses that flag rather than recomputing
|
|
23702
|
+
* hold/revert semantics a second time here.
|
|
23703
|
+
*
|
|
23704
|
+
* @module render/animation-text-style-resolve
|
|
23705
|
+
*/
|
|
23706
|
+
/** The three boolean-valued style attrs a `p:set`/`p:anim` can drive. */
|
|
23707
|
+
const BOOLEAN_ATTR_FIELD = {
|
|
23708
|
+
'style.fontweight': 'bold',
|
|
23709
|
+
'style.fontstyle': 'italic',
|
|
23710
|
+
'style.textdecorationunderline': 'underline',
|
|
23711
|
+
// Tolerate the shorter spelling some non-PowerPoint producers use.
|
|
23712
|
+
'style.underline': 'underline',
|
|
23713
|
+
};
|
|
23714
|
+
const RECOGNIZED_ATTRS = new Set([
|
|
23715
|
+
...Object.keys(BOOLEAN_ATTR_FIELD),
|
|
23716
|
+
'style.fontsize',
|
|
23717
|
+
'style.color',
|
|
23718
|
+
]);
|
|
23719
|
+
/** Decode a `p:set`/`p:tav` value into the boolean a style attr expects. */
|
|
23720
|
+
function decodeBooleanAttr(attrName, value) {
|
|
23721
|
+
if (typeof value === 'boolean') {
|
|
23722
|
+
return value;
|
|
23723
|
+
}
|
|
23724
|
+
if (typeof value === 'number') {
|
|
23725
|
+
return value !== 0;
|
|
23726
|
+
}
|
|
23727
|
+
const normalized = value.trim().toLowerCase();
|
|
23728
|
+
if (normalized === 'true' || normalized === '1') {
|
|
23729
|
+
return true;
|
|
23730
|
+
}
|
|
23731
|
+
if (normalized === 'false' || normalized === '0' || normalized === '') {
|
|
23732
|
+
return false;
|
|
23733
|
+
}
|
|
23734
|
+
if (attrName === 'style.fontweight') {
|
|
23735
|
+
return normalized === 'bold' || normalized === '700';
|
|
23736
|
+
}
|
|
23737
|
+
if (attrName === 'style.fontstyle') {
|
|
23738
|
+
return normalized === 'italic';
|
|
23739
|
+
}
|
|
23740
|
+
return normalized === 'underline';
|
|
23741
|
+
}
|
|
23742
|
+
/** Apply one decoded (attrName, value) pair onto the descriptor being built. */
|
|
23743
|
+
function applyDecodedValue(descriptor, attrName, value) {
|
|
23744
|
+
const boolField = BOOLEAN_ATTR_FIELD[attrName];
|
|
23745
|
+
if (boolField) {
|
|
23746
|
+
descriptor[boolField] = decodeBooleanAttr(attrName, value);
|
|
23747
|
+
return;
|
|
23748
|
+
}
|
|
23749
|
+
if (attrName === 'style.color' && typeof value === 'string' && value !== '') {
|
|
23750
|
+
descriptor.color = value;
|
|
23751
|
+
}
|
|
23752
|
+
}
|
|
23753
|
+
function applySetAnimation(descriptor, entry) {
|
|
23754
|
+
applyDecodedValue(descriptor, entry.attrName, entry.value);
|
|
23755
|
+
}
|
|
23756
|
+
/**
|
|
23757
|
+
* Apply one `p:anim` ramp component. `style.fontsize` is read as a
|
|
23758
|
+
* first-stop -> last-stop RATIO (see the module doc). A boolean attr (Bold
|
|
23759
|
+
* Flash's `style.fontweight`) is read as "true if ANY stop is true", not just
|
|
23760
|
+
* the last: PowerPoint composes the whole flash-and-revert pattern (e.g.
|
|
23761
|
+
* normal -> bold -> normal) inside the SAME ramp, so reading only the final
|
|
23762
|
+
* stop would resolve to "never bold" and the flash would never render at
|
|
23763
|
+
* all. `style.color`'s last stop is used as-is (there is no boolean
|
|
23764
|
+
* "any"-style reading for a colour).
|
|
23765
|
+
*/
|
|
23766
|
+
function applyAttributeRamp(descriptor, component) {
|
|
23767
|
+
const stops = component.keyframes;
|
|
23768
|
+
if (stops.length === 0) {
|
|
23769
|
+
return;
|
|
23770
|
+
}
|
|
23771
|
+
const last = stops[stops.length - 1];
|
|
23772
|
+
if (component.attrName === 'style.fontsize') {
|
|
23773
|
+
const firstNumeric = Number(stops[0].value);
|
|
23774
|
+
const lastNumeric = Number(last.value);
|
|
23775
|
+
if (Number.isFinite(firstNumeric) && firstNumeric !== 0 && Number.isFinite(lastNumeric)) {
|
|
23776
|
+
descriptor.fontScale = lastNumeric / firstNumeric;
|
|
23777
|
+
}
|
|
23778
|
+
return;
|
|
23779
|
+
}
|
|
23780
|
+
const boolField = BOOLEAN_ATTR_FIELD[component.attrName];
|
|
23781
|
+
if (boolField) {
|
|
23782
|
+
descriptor[boolField] = stops.some((stop) => decodeBooleanAttr(component.attrName, stop.value));
|
|
23783
|
+
return;
|
|
23784
|
+
}
|
|
23785
|
+
applyDecodedValue(descriptor, component.attrName, last.value);
|
|
23786
|
+
}
|
|
23787
|
+
/**
|
|
23788
|
+
* Resolve the text-style override an authored effect composes via `p:set`
|
|
23789
|
+
* siblings and/or a `style.fontsize`/boolean `p:anim` ramp. Returns
|
|
23790
|
+
* `undefined` when the effect carries none of the recognised attrs, so a
|
|
23791
|
+
* caller can fall back to the neutral emphasis animation exactly as before.
|
|
23792
|
+
*/
|
|
23793
|
+
function resolveTextStyleAnimation(anim) {
|
|
23794
|
+
const descriptor = {};
|
|
23795
|
+
for (const entry of anim.setAnimations ?? []) {
|
|
23796
|
+
applySetAnimation(descriptor, entry);
|
|
23797
|
+
}
|
|
23798
|
+
for (const component of anim.attributeAnimations ?? []) {
|
|
23799
|
+
if (RECOGNIZED_ATTRS.has(component.attrName)) {
|
|
23800
|
+
applyAttributeRamp(descriptor, component);
|
|
23801
|
+
}
|
|
23802
|
+
}
|
|
23803
|
+
return Object.keys(descriptor).length > 0 ? descriptor : undefined;
|
|
23804
|
+
}
|
|
23805
|
+
|
|
23806
|
+
/**
|
|
23807
|
+
* `animation-text-style-css` - builds a scoped, `!important` CSS rule that
|
|
23808
|
+
* applies an active {@link TextStyleAnimationDescriptor} on top of an
|
|
23809
|
+
* element's own rendered text runs.
|
|
23810
|
+
*
|
|
23811
|
+
* Every binding already stamps its top-level rendered element wrapper with
|
|
23812
|
+
* `data-element-id="<id>"` (selection, hit-testing, the four non-React
|
|
23813
|
+
* bindings' post-render DOM pass). A run span always carries its OWN inline
|
|
23814
|
+
* `style` attribute (bold/italic/underline/size are declared there
|
|
23815
|
+
* unconditionally, see `text-run-style.ts`), so plain CSS inheritance from an
|
|
23816
|
+
* ancestor can never reach it: only a stylesheet rule with `!important`
|
|
23817
|
+
* outranks another element's own inline style. Scoping the selector to this
|
|
23818
|
+
* element's `data-element-id` keeps the override from leaking onto sibling
|
|
23819
|
+
* elements that reuse the same generic run markup.
|
|
23820
|
+
*
|
|
23821
|
+
* `fontScale` is applied as `calc(1em * <scale>)` rather than an absolute
|
|
23822
|
+
* size: once this rule wins, the run's own inline `font-size` is not
|
|
23823
|
+
* consulted at all, so the `em` here resolves against the INHERITED
|
|
23824
|
+
* (ancestor) font-size, giving a reasonable relative-size approximation
|
|
23825
|
+
* without needing per-run size bookkeeping at the override layer.
|
|
23826
|
+
*
|
|
23827
|
+
* @module render/animation-text-style-css
|
|
23828
|
+
*/
|
|
23829
|
+
/** Escape a value for safe use inside a double-quoted CSS attribute selector. */
|
|
23830
|
+
function escapeCssAttributeValue$1(value) {
|
|
23831
|
+
return value.replaceAll('\\', '\\\\').replaceAll('"', '\\"');
|
|
23832
|
+
}
|
|
23833
|
+
/**
|
|
23834
|
+
* Build the CSS override rule for one element's active text-style animation,
|
|
23835
|
+
* or `undefined` when there is nothing to override (so a binding can skip
|
|
23836
|
+
* rendering a `<style>` tag entirely).
|
|
23837
|
+
*
|
|
23838
|
+
* Emits TWO scoped rules, both keyed off the SAME `data-element-id`, so one
|
|
23839
|
+
* call covers every element type a font-style emphasis effect can target
|
|
23840
|
+
* (text/shape, a table cell, a connector caption, a chart title/label/legend,
|
|
23841
|
+
* a SmartArt node caption): a binding no longer needs to gate this call on
|
|
23842
|
+
* "is this a plain text element" - PowerPoint animates a table cell or a
|
|
23843
|
+
* chart title exactly the same way.
|
|
23844
|
+
*
|
|
23845
|
+
* - The `[style]` rule targets ordinary HTML text (paragraph runs, table
|
|
23846
|
+
* cell spans, connector caption spans): every one of those already carries
|
|
23847
|
+
* its OWN inline `style` attribute (see the module doc), which plain CSS
|
|
23848
|
+
* inheritance cannot reach.
|
|
23849
|
+
* - The `text, tspan` rule targets SVG text (chart titles/axis
|
|
23850
|
+
* labels/data labels/legend, SmartArt node captions): every binding draws
|
|
23851
|
+
* those as raw SVG presentation ATTRIBUTES (`fill=`, `font-weight=`, ...),
|
|
23852
|
+
* never an inline `style`, so the `[style]` rule's selector never matches
|
|
23853
|
+
* them at all. `font-weight`/`font-style`/`font-size`/`text-decoration`
|
|
23854
|
+
* are CSS properties SVG text already honours; `color` is not (SVG paints
|
|
23855
|
+
* text via `fill`), so the colour case is re-expressed as `fill` here
|
|
23856
|
+
* instead of reusing the `color` declaration.
|
|
23857
|
+
*
|
|
23858
|
+
* Neither rule leaks onto a chart's non-text SVG (bars, slices, borders):
|
|
23859
|
+
* `text, tspan` is a plain type selector, not `*`, so nothing else in the
|
|
23860
|
+
* element's subtree matches it.
|
|
23861
|
+
*/
|
|
23862
|
+
function buildTextStyleOverrideCss(elementId, style) {
|
|
23863
|
+
if (!style) {
|
|
23864
|
+
return undefined;
|
|
23865
|
+
}
|
|
23866
|
+
const declarations = [];
|
|
23867
|
+
const svgDeclarations = [];
|
|
23868
|
+
if (style.bold !== undefined) {
|
|
23869
|
+
const decl = `font-weight: ${style.bold ? 'bold' : 'normal'} !important;`;
|
|
23870
|
+
declarations.push(decl);
|
|
23871
|
+
svgDeclarations.push(decl);
|
|
23872
|
+
}
|
|
23873
|
+
if (style.italic !== undefined) {
|
|
23874
|
+
const decl = `font-style: ${style.italic ? 'italic' : 'normal'} !important;`;
|
|
23875
|
+
declarations.push(decl);
|
|
23876
|
+
svgDeclarations.push(decl);
|
|
23877
|
+
}
|
|
23878
|
+
if (style.underline !== undefined) {
|
|
23879
|
+
const decl = `text-decoration-line: ${style.underline ? 'underline' : 'none'} !important;`;
|
|
23880
|
+
declarations.push(decl);
|
|
23881
|
+
svgDeclarations.push(decl);
|
|
23882
|
+
}
|
|
23883
|
+
if (typeof style.fontScale === 'number' &&
|
|
23884
|
+
Number.isFinite(style.fontScale) &&
|
|
23885
|
+
style.fontScale > 0) {
|
|
23886
|
+
const decl = `font-size: calc(1em * ${style.fontScale}) !important;`;
|
|
23887
|
+
declarations.push(decl);
|
|
23888
|
+
svgDeclarations.push(decl);
|
|
23889
|
+
}
|
|
23890
|
+
if (style.color) {
|
|
23891
|
+
declarations.push(`color: ${style.color} !important;`);
|
|
23892
|
+
svgDeclarations.push(`fill: ${style.color} !important;`);
|
|
23893
|
+
}
|
|
23894
|
+
if (declarations.length === 0) {
|
|
23895
|
+
return undefined;
|
|
23896
|
+
}
|
|
23897
|
+
const scope = `[data-element-id="${escapeCssAttributeValue$1(elementId)}"]`;
|
|
23898
|
+
const htmlRule = `${scope} [style] { ${declarations.join(' ')} }`;
|
|
23899
|
+
const svgRule = `${scope} text, ${scope} tspan { ${svgDeclarations.join(' ')} }`;
|
|
23900
|
+
return `${htmlRule}\n${svgRule}`;
|
|
23901
|
+
}
|
|
23902
|
+
/**
|
|
23903
|
+
* A visually inert `@keyframes` block for an emphasis step whose ONLY effect
|
|
23904
|
+
* is a text-style change (Bold Reveal, Underline, Style Emphasis, ...).
|
|
23905
|
+
*
|
|
23906
|
+
* The timeline builder needs every step to own a CSS animation so the
|
|
23907
|
+
* playback engine's timing (delay, duration, cleanup) has something to hang
|
|
23908
|
+
* off, but the unmapped-preset safety net used to hand these steps a neutral
|
|
23909
|
+
* `pulse`, so PowerPoint's plain "the text turns bold" played with a scale
|
|
23910
|
+
* throb on top. This keyframe holds the element exactly as rendered while the
|
|
23911
|
+
* `textStyle` override does the visible work.
|
|
23912
|
+
*/
|
|
23913
|
+
function buildTextStyleHoldKeyframe(uid) {
|
|
23914
|
+
const keyframeName = `pptx-tl-textstyle-hold-${uid}`;
|
|
23915
|
+
return {
|
|
23916
|
+
keyframeName,
|
|
23917
|
+
css: `@keyframes ${keyframeName} {\n\tfrom { opacity: 1; }\n\tto { opacity: 1; }\n}`,
|
|
23918
|
+
};
|
|
23919
|
+
}
|
|
23920
|
+
|
|
23921
|
+
/**
|
|
23922
|
+
* `animation-text-style-state` - pure merge/revert helpers for carrying a
|
|
23923
|
+
* {@link TextStyleAnimationDescriptor} through `animation-playback-engine.ts`'s
|
|
23924
|
+
* step-start and step-cleanup writes, mirroring how `carryBuildState` already
|
|
23925
|
+
* carries `build`/`chartReveal`/`diagramReveal` forward so one step's write
|
|
23926
|
+
* never clobbers a concern a DIFFERENT still-active step on the same element
|
|
23927
|
+
* owns.
|
|
23928
|
+
*
|
|
23929
|
+
* @module render/animation-text-style-state
|
|
23930
|
+
*/
|
|
23931
|
+
/**
|
|
23932
|
+
* Merge a step's text-style override onto whatever the element already
|
|
23933
|
+
* carries (from a still-active earlier step), on step START. The new step's
|
|
23934
|
+
* fields win on a conflict; fields it does not mention pass through
|
|
23935
|
+
* unchanged.
|
|
23936
|
+
*/
|
|
23937
|
+
function mergeTextStyleOnStart(carried, stepStyle) {
|
|
23938
|
+
if (!stepStyle) {
|
|
23939
|
+
return carried;
|
|
23940
|
+
}
|
|
23941
|
+
return { ...carried, ...stepStyle };
|
|
23942
|
+
}
|
|
23943
|
+
/**
|
|
23944
|
+
* Resolve the text-style override left after a step's CLEANUP.
|
|
23945
|
+
*
|
|
23946
|
+
* `holdEndState` mirrors `p:cTn/@fill="hold"/"freeze"/"transition"` (see
|
|
23947
|
+
* `animation-fill-repeat.ts`'s `shouldHoldEndState`, the same flag that keeps
|
|
23948
|
+
* a CSS animation's final frame attached instead of clearing it): when set,
|
|
23949
|
+
* the step's fields stay merged in permanently; otherwise only the KEYS this
|
|
23950
|
+
* step itself set are reverted, so a different still-active step's fields
|
|
23951
|
+
* (e.g. a concurrent colour change) are not clobbered.
|
|
23952
|
+
*/
|
|
23953
|
+
function resolveTextStyleOnCleanup(carried, stepStyle, holdEndState) {
|
|
23954
|
+
if (!stepStyle) {
|
|
23955
|
+
return carried;
|
|
23956
|
+
}
|
|
23957
|
+
if (holdEndState) {
|
|
23958
|
+
return { ...carried, ...stepStyle };
|
|
23959
|
+
}
|
|
23960
|
+
if (!carried) {
|
|
23961
|
+
return undefined;
|
|
23962
|
+
}
|
|
23963
|
+
const remaining = { ...carried };
|
|
23964
|
+
for (const key of Object.keys(stepStyle)) {
|
|
23965
|
+
delete remaining[key];
|
|
23966
|
+
}
|
|
23967
|
+
return Object.keys(remaining).length > 0 ? remaining : undefined;
|
|
23968
|
+
}
|
|
23969
|
+
|
|
23338
23970
|
/**
|
|
23339
23971
|
* `animation-filter-random`: resolves the `random` SMIL/ECMA-376
|
|
23340
23972
|
* `p:animEffect/@filter` family (see `animation-filter-effects`'s module doc
|
|
@@ -24063,6 +24695,19 @@ const EXIT_KEYFRAME_DEFINITIONS = {
|
|
|
24063
24695
|
0% { opacity: 1; }
|
|
24064
24696
|
99% { opacity: 1; }
|
|
24065
24697
|
100% { opacity: 0; }
|
|
24698
|
+
}`,
|
|
24699
|
+
// Flash Once (exit.11), verified via COM: `msoAnimEffectFlashOnce` with
|
|
24700
|
+
// `Effect.Exit = True` serializes as presetID 11 with no `@filter` (the
|
|
24701
|
+
// exit-gallery counterpart of entr.11's `flashIn`, which also carries no
|
|
24702
|
+
// filter). The real authored effect is a `style.visibility` set pair
|
|
24703
|
+
// (hidden/visible flashed a few times); this mirrors `flashIn`'s opacity
|
|
24704
|
+
// flicker but ends HIDDEN rather than visible, since this is an exit.
|
|
24705
|
+
flashOnceOut: `@keyframes pptx-flashOnceOut {
|
|
24706
|
+
0% { opacity: 1; }
|
|
24707
|
+
25% { opacity: 0; }
|
|
24708
|
+
50% { opacity: 1; }
|
|
24709
|
+
75% { opacity: 0; }
|
|
24710
|
+
100% { opacity: 0; }
|
|
24066
24711
|
}`,
|
|
24067
24712
|
};
|
|
24068
24713
|
|
|
@@ -24125,6 +24770,19 @@ const EXIT_SHAPE_KEYFRAME_DEFINITIONS = {
|
|
|
24125
24770
|
peekOut: `@keyframes pptx-peekOut {
|
|
24126
24771
|
from { ${maskEdgeDecl('bottom', 'shown')} opacity: 1; }
|
|
24127
24772
|
to { ${maskEdgeDecl('bottom', 'hidden')} opacity: 0; }
|
|
24773
|
+
}`,
|
|
24774
|
+
// Peek Out (exit.12), verified via COM (this repo's own PowerShell
|
|
24775
|
+
// automation): `AddEffect` with the Peek In `MsoAnimEffect` constant then
|
|
24776
|
+
// `Effect.Exit = True` re-emits `presetID="12" presetSubtype="4"` with a
|
|
24777
|
+
// child `p:animEffect[@filter="wipe(down)"]` - a DIFFERENT, distinct
|
|
24778
|
+
// preset id from exit.16 above (whose own "Peek Out" naming is a
|
|
24779
|
+
// pre-existing, out-of-scope mismatch; see that entry's note), so this
|
|
24780
|
+
// gets its own non-colliding keyframe name. `presetSubtype="4"` is the
|
|
24781
|
+
// bottom-edge bit (matching entr.12's `peekIn`, also bottom-origin), so
|
|
24782
|
+
// this reuses the identical mask technique.
|
|
24783
|
+
peekOutDown: `@keyframes pptx-peekOutDown {
|
|
24784
|
+
from { ${maskEdgeDecl('bottom', 'shown')} opacity: 1; }
|
|
24785
|
+
to { ${maskEdgeDecl('bottom', 'hidden')} opacity: 0; }
|
|
24128
24786
|
}`,
|
|
24129
24787
|
// Split (exit.17): the exit-gallery counterpart of Split, closing the
|
|
24130
24788
|
// centred band back to nothing rather than growing it outward.
|
|
@@ -24860,11 +25518,12 @@ function revealedStageCount(progress, totalStages) {
|
|
|
24860
25518
|
// State folding
|
|
24861
25519
|
// ==========================================================================
|
|
24862
25520
|
/**
|
|
24863
|
-
* Fold a revealing step's staged-build + colour-target
|
|
24864
|
-
* {@link ElementAnimationState}. Mutates `state` in
|
|
24865
|
-
* (with progress resolved at `options.elapsedMs`),
|
|
24866
|
-
* `animatesStroke` only when the step
|
|
24867
|
-
* plain whole-element entrance
|
|
25521
|
+
* Fold a revealing step's staged-build + colour-target + text-style
|
|
25522
|
+
* descriptors onto an {@link ElementAnimationState}. Mutates `state` in
|
|
25523
|
+
* place, adding `build` (with progress resolved at `options.elapsedMs`),
|
|
25524
|
+
* `animatesFill`, `animatesStroke`, and `textStyle` only when the step
|
|
25525
|
+
* actually carries those descriptors, so a plain whole-element entrance
|
|
25526
|
+
* leaves the state untouched.
|
|
24868
25527
|
*/
|
|
24869
25528
|
function applyStepBuildMetadata(state, step, options) {
|
|
24870
25529
|
if (!step) {
|
|
@@ -24882,6 +25541,9 @@ function applyStepBuildMetadata(state, step, options) {
|
|
|
24882
25541
|
state.animatesStroke = true;
|
|
24883
25542
|
}
|
|
24884
25543
|
}
|
|
25544
|
+
if (step.textStyle) {
|
|
25545
|
+
state.textStyle = step.textStyle;
|
|
25546
|
+
}
|
|
24885
25547
|
}
|
|
24886
25548
|
|
|
24887
25549
|
/**
|
|
@@ -28452,6 +29114,14 @@ function fallbackEffectForClass(presetClass) {
|
|
|
28452
29114
|
}
|
|
28453
29115
|
return undefined;
|
|
28454
29116
|
}
|
|
29117
|
+
/**
|
|
29118
|
+
* An emphasis whose visible work is entirely a `p:set`/`p:anim` text-style
|
|
29119
|
+
* change (no mapped preset effect, no transform). Such a step must not fall
|
|
29120
|
+
* through to the neutral `pulse` safety net.
|
|
29121
|
+
*/
|
|
29122
|
+
function isTextStyleOnlyEmphasis(anim) {
|
|
29123
|
+
return anim.presetClass === 'emph' && resolveTextStyleAnimation(anim) !== undefined;
|
|
29124
|
+
}
|
|
28455
29125
|
// ==========================================================================
|
|
28456
29126
|
// Timeline builder
|
|
28457
29127
|
// ==========================================================================
|
|
@@ -28600,11 +29270,19 @@ function buildTimeline(nativeAnimations) {
|
|
|
28600
29270
|
// sequenced so the playback layer can act on it at the right time.
|
|
28601
29271
|
const isCommand = !effect && !dynamic && isMediaCommandAnimation(singleAnim);
|
|
28602
29272
|
if (!effect && !dynamic && !isCommand) {
|
|
28603
|
-
|
|
28604
|
-
|
|
28605
|
-
|
|
28606
|
-
|
|
28607
|
-
|
|
29273
|
+
if (isTextStyleOnlyEmphasis(singleAnim)) {
|
|
29274
|
+
// Bold Reveal / Underline / Style Emphasis: the `textStyle`
|
|
29275
|
+
// override is the whole effect, so hold the element still
|
|
29276
|
+
// instead of layering the neutral pulse on top of it.
|
|
29277
|
+
dynamic = buildTextStyleHoldKeyframe(dynamicUid++);
|
|
29278
|
+
}
|
|
29279
|
+
else {
|
|
29280
|
+
// Unmapped preset: fall back so an entrance is still hidden until
|
|
29281
|
+
// its start and an exit still hides, rather than being dropped.
|
|
29282
|
+
effect = fallbackEffectForClass(singleAnim.presetClass);
|
|
29283
|
+
if (!effect) {
|
|
29284
|
+
continue;
|
|
29285
|
+
}
|
|
28608
29286
|
}
|
|
28609
29287
|
}
|
|
28610
29288
|
let keyframe = '';
|
|
@@ -28763,6 +29441,7 @@ function buildTimeline(nativeAnimations) {
|
|
|
28763
29441
|
build: isCommand ? undefined : resolveStepBuildDescriptor(singleAnim),
|
|
28764
29442
|
graphicElement: isCommand ? undefined : extractStepGraphicElement(singleAnim),
|
|
28765
29443
|
colorTargets: isCommand ? undefined : stepColorTargets(singleAnim, tavColorApplied),
|
|
29444
|
+
textStyle: isCommand ? undefined : resolveTextStyleAnimation(singleAnim),
|
|
28766
29445
|
holdEndState: afterFields.holdEndState || undefined,
|
|
28767
29446
|
hideAfterEffect: afterFields.hideAfterEffect,
|
|
28768
29447
|
pendingHideOnNextClick: afterFields.pendingHideOnNextClick,
|
|
@@ -28916,10 +29595,15 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
|
|
|
28916
29595
|
// command was dropped in silence.
|
|
28917
29596
|
const isCommand = !effect && !dynamic && isMediaCommandAnimation(anim);
|
|
28918
29597
|
if (!effect && !dynamic && !isCommand) {
|
|
28919
|
-
|
|
28920
|
-
|
|
28921
|
-
|
|
28922
|
-
|
|
29598
|
+
if (isTextStyleOnlyEmphasis(anim)) {
|
|
29599
|
+
dynamic = buildTextStyleHoldKeyframe(dynamicUid++);
|
|
29600
|
+
}
|
|
29601
|
+
else {
|
|
29602
|
+
// Same unmapped-preset safety net as the main timeline loop.
|
|
29603
|
+
effect = fallbackEffectForClass(anim.presetClass);
|
|
29604
|
+
if (!effect) {
|
|
29605
|
+
continue;
|
|
29606
|
+
}
|
|
28923
29607
|
}
|
|
28924
29608
|
}
|
|
28925
29609
|
const keyframe = isCommand ? '' : effect ? cssKeyframeName(effect) : dynamic.keyframeName;
|
|
@@ -29006,6 +29690,7 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
|
|
|
29006
29690
|
build: isCommand ? undefined : resolveStepBuildDescriptor(anim),
|
|
29007
29691
|
graphicElement: isCommand ? undefined : extractStepGraphicElement(anim),
|
|
29008
29692
|
colorTargets: isCommand ? undefined : stepColorTargets(anim, tavColorApplied),
|
|
29693
|
+
textStyle: isCommand ? undefined : resolveTextStyleAnimation(anim),
|
|
29009
29694
|
holdEndState: afterFields.holdEndState || undefined,
|
|
29010
29695
|
hideAfterEffect: afterFields.hideAfterEffect,
|
|
29011
29696
|
pendingHideOnNextClick: afterFields.pendingHideOnNextClick,
|
|
@@ -38054,7 +38739,7 @@ const animationPresetTranslationsEn = {
|
|
|
38054
38739
|
'pptx.animation.catalogPreset.entr8': 'Diamond',
|
|
38055
38740
|
'pptx.animation.catalogPreset.entr9': 'Dissolve In',
|
|
38056
38741
|
'pptx.animation.catalogPreset.entr10': 'Fade',
|
|
38057
|
-
'pptx.animation.catalogPreset.entr11': 'Flash
|
|
38742
|
+
'pptx.animation.catalogPreset.entr11': 'Flash Once',
|
|
38058
38743
|
'pptx.animation.catalogPreset.entr12': 'Flash Once',
|
|
38059
38744
|
'pptx.animation.catalogPreset.entr13': 'Plus',
|
|
38060
38745
|
'pptx.animation.catalogPreset.entr14': 'Random Bars',
|
|
@@ -38123,8 +38808,8 @@ const animationPresetTranslationsEn = {
|
|
|
38123
38808
|
'pptx.animation.catalogPreset.exit8': 'Diamond',
|
|
38124
38809
|
'pptx.animation.catalogPreset.exit9': 'Dissolve Out',
|
|
38125
38810
|
'pptx.animation.catalogPreset.exit10': 'Fade',
|
|
38126
|
-
'pptx.animation.catalogPreset.exit11': 'Flash
|
|
38127
|
-
'pptx.animation.catalogPreset.exit12': '
|
|
38811
|
+
'pptx.animation.catalogPreset.exit11': 'Flash Once',
|
|
38812
|
+
'pptx.animation.catalogPreset.exit12': 'Peek Out',
|
|
38128
38813
|
'pptx.animation.catalogPreset.exit13': 'Plus',
|
|
38129
38814
|
'pptx.animation.catalogPreset.exit14': 'Random Bars',
|
|
38130
38815
|
'pptx.animation.catalogPreset.exit15': 'Spiral Out',
|
|
@@ -38483,6 +39168,12 @@ const translationsEn = {
|
|
|
38483
39168
|
'pptx.accessibility.error': 'Error: ',
|
|
38484
39169
|
'pptx.accessibility.warning': 'Warning: ',
|
|
38485
39170
|
'pptx.accessibility.info': 'Info: ',
|
|
39171
|
+
// Element-level alt text / title (shape, text box, connector). A picture's
|
|
39172
|
+
// own alt text field uses `pptx.image.altText` / `pptx.image.altTextPlaceholder`.
|
|
39173
|
+
'pptx.elementAccessibility.altText': 'Alt text',
|
|
39174
|
+
'pptx.elementAccessibility.altTextPlaceholder': 'Describe this element for accessibility',
|
|
39175
|
+
'pptx.elementAccessibility.title': 'Title',
|
|
39176
|
+
'pptx.elementAccessibility.titlePlaceholder': 'Accessibility title (optional)',
|
|
38486
39177
|
// Animations
|
|
38487
39178
|
'pptx.animations.previewTooltip': 'Preview animation on selected element',
|
|
38488
39179
|
'pptx.animations.preview': 'Preview',
|
|
@@ -41746,6 +42437,51 @@ const translationsEn = {
|
|
|
41746
42437
|
'pptx.hyperlink.actionOpenPresentation': 'Open presentation',
|
|
41747
42438
|
'pptx.hyperlink.actionPlayMedia': 'Play media',
|
|
41748
42439
|
'pptx.hyperlink.actionOleVerb': 'Object action',
|
|
42440
|
+
// Table style (a:tblStyleLst) definition editor.
|
|
42441
|
+
'pptx.tableStyleEditor.editButton': 'Edit style...',
|
|
42442
|
+
'pptx.tableStyleEditor.title': 'Table Style Editor',
|
|
42443
|
+
'pptx.tableStyleEditor.close': 'Close',
|
|
42444
|
+
'pptx.tableStyleEditor.noStyleSelected': 'Select a table style to edit its definition.',
|
|
42445
|
+
'pptx.tableStyleEditor.styleName': 'Style name',
|
|
42446
|
+
'pptx.tableStyleEditor.sections': 'Sections',
|
|
42447
|
+
'pptx.tableStyleEditor.newFromCurrent': 'New style from current',
|
|
42448
|
+
'pptx.tableStyleEditor.newStyle': 'Create new style',
|
|
42449
|
+
'pptx.tableStyleEditor.deleteStyle': 'Delete style',
|
|
42450
|
+
'pptx.tableStyleEditor.deleteConfirm': 'Delete this table style? This cannot be undone.',
|
|
42451
|
+
'pptx.tableStyleEditor.newStyleNamePrompt': 'Name for the new style',
|
|
42452
|
+
'pptx.tableStyleEditor.part.wholeTbl': 'Whole Table',
|
|
42453
|
+
'pptx.tableStyleEditor.part.firstRow': 'First Row',
|
|
42454
|
+
'pptx.tableStyleEditor.part.lastRow': 'Last Row',
|
|
42455
|
+
'pptx.tableStyleEditor.part.firstCol': 'First Column',
|
|
42456
|
+
'pptx.tableStyleEditor.part.lastCol': 'Last Column',
|
|
42457
|
+
'pptx.tableStyleEditor.part.band1H': 'Band 1 Horizontal',
|
|
42458
|
+
'pptx.tableStyleEditor.part.band2H': 'Band 2 Horizontal',
|
|
42459
|
+
'pptx.tableStyleEditor.part.band1V': 'Band 1 Vertical',
|
|
42460
|
+
'pptx.tableStyleEditor.part.band2V': 'Band 2 Vertical',
|
|
42461
|
+
'pptx.tableStyleEditor.part.neCell': 'NE Cell',
|
|
42462
|
+
'pptx.tableStyleEditor.part.nwCell': 'NW Cell',
|
|
42463
|
+
'pptx.tableStyleEditor.part.seCell': 'SE Cell',
|
|
42464
|
+
'pptx.tableStyleEditor.part.swCell': 'SW Cell',
|
|
42465
|
+
'pptx.tableStyleEditor.part.background': 'Background',
|
|
42466
|
+
'pptx.tableStyleEditor.fillSection': 'Fill',
|
|
42467
|
+
'pptx.tableStyleEditor.noFill': 'No fill',
|
|
42468
|
+
'pptx.tableStyleEditor.textSection': 'Text',
|
|
42469
|
+
'pptx.tableStyleEditor.textColor': 'Text color',
|
|
42470
|
+
'pptx.tableStyleEditor.bordersSection': 'Borders',
|
|
42471
|
+
'pptx.tableStyleEditor.borderDash': 'Dash style',
|
|
42472
|
+
'pptx.tableStyleEditor.noBorder': 'No border',
|
|
42473
|
+
'pptx.tableStyleEditor.cell3DSection': '3D bevel',
|
|
42474
|
+
'pptx.tableStyleEditor.bevelWidth': 'Bevel width',
|
|
42475
|
+
'pptx.tableStyleEditor.bevelHeight': 'Bevel height',
|
|
42476
|
+
'pptx.tableStyleEditor.bevelPreset': 'Bevel preset',
|
|
42477
|
+
'pptx.tableStyleEditor.side.left': 'Left',
|
|
42478
|
+
'pptx.tableStyleEditor.side.right': 'Right',
|
|
42479
|
+
'pptx.tableStyleEditor.side.top': 'Top',
|
|
42480
|
+
'pptx.tableStyleEditor.side.bottom': 'Bottom',
|
|
42481
|
+
'pptx.tableStyleEditor.side.insideH': 'Inside horizontal',
|
|
42482
|
+
'pptx.tableStyleEditor.side.insideV': 'Inside vertical',
|
|
42483
|
+
'pptx.tableStyleEditor.side.tl2br': 'Diagonal top-left to bottom-right',
|
|
42484
|
+
'pptx.tableStyleEditor.side.tr2bl': 'Diagonal top-right to bottom-left',
|
|
41749
42485
|
};
|
|
41750
42486
|
/**
|
|
41751
42487
|
* Convert a dotted translation key to a human-readable label when no
|
|
@@ -57843,7 +58579,7 @@ function createWriteBackScheduler(deps) {
|
|
|
57843
58579
|
const merged = deps.mergeTemplateElements
|
|
57844
58580
|
? deps.mergeTemplateElements(slides, deps.getTemplateElements?.() ?? {})
|
|
57845
58581
|
: slides;
|
|
57846
|
-
const bytes = await handler.save(merged);
|
|
58582
|
+
const bytes = await handler.save(merged, deps.getSaveOptions?.());
|
|
57847
58583
|
config.onWriteBack(bytes);
|
|
57848
58584
|
}
|
|
57849
58585
|
catch {
|
|
@@ -76208,6 +76944,79 @@ function applyRenderedElementAccessibility(stage, elements, options = {}) {
|
|
|
76208
76944
|
return applied;
|
|
76209
76945
|
}
|
|
76210
76946
|
|
|
76947
|
+
/**
|
|
76948
|
+
* Which element kinds model an accessibility description (`altText`) and
|
|
76949
|
+
* title (`title`) on `p:cNvPr` (`@descr` / `@title`, `PptxNonVisualDescription`
|
|
76950
|
+
* in core), and a pure descriptor every binding's inspector can use to decide
|
|
76951
|
+
* whether to show the alt-text / title editing fields for the selected
|
|
76952
|
+
* element.
|
|
76953
|
+
*
|
|
76954
|
+
* Before this module existed, a picture's own alt-text field was the only
|
|
76955
|
+
* one any binding's inspector rendered; a plain shape, text box or connector
|
|
76956
|
+
* had nowhere to author the same PowerPoint Accessibility-pane text even
|
|
76957
|
+
* after core started parsing it. Centralising the "which element kinds get
|
|
76958
|
+
* which field" decision here means a new kind reaches every binding's
|
|
76959
|
+
* inspector by editing one set, not five.
|
|
76960
|
+
*
|
|
76961
|
+
* @module render/element-non-visual-description
|
|
76962
|
+
*/
|
|
76963
|
+
/** Element kinds whose core type models `altText` (`p:cNvPr/@descr`). */
|
|
76964
|
+
const ALT_TEXT_ELEMENT_TYPES = new Set([
|
|
76965
|
+
'image',
|
|
76966
|
+
'picture',
|
|
76967
|
+
'table',
|
|
76968
|
+
'chart',
|
|
76969
|
+
'smartArt',
|
|
76970
|
+
'ole',
|
|
76971
|
+
'media',
|
|
76972
|
+
'text',
|
|
76973
|
+
'shape',
|
|
76974
|
+
'connector',
|
|
76975
|
+
]);
|
|
76976
|
+
/**
|
|
76977
|
+
* Element kinds whose core type models `title` (`p:cNvPr/@title`). A picture
|
|
76978
|
+
* is deliberately excluded: `ImagePptxElement`/`PicturePptxElement` only ever
|
|
76979
|
+
* carry `altText` (no `title` field), matching how PowerPoint's own Alt Text
|
|
76980
|
+
* pane has no separate title box for a picture.
|
|
76981
|
+
*/
|
|
76982
|
+
const TITLE_ELEMENT_TYPES = new Set([
|
|
76983
|
+
'table',
|
|
76984
|
+
'chart',
|
|
76985
|
+
'smartArt',
|
|
76986
|
+
'ole',
|
|
76987
|
+
'media',
|
|
76988
|
+
'text',
|
|
76989
|
+
'shape',
|
|
76990
|
+
'connector',
|
|
76991
|
+
]);
|
|
76992
|
+
/** Whether `type`'s core element models an `altText` field. */
|
|
76993
|
+
function supportsAltTextField(type) {
|
|
76994
|
+
return ALT_TEXT_ELEMENT_TYPES.has(type);
|
|
76995
|
+
}
|
|
76996
|
+
/** Whether `type`'s core element models a `title` field. */
|
|
76997
|
+
function supportsTitleField(type) {
|
|
76998
|
+
return TITLE_ELEMENT_TYPES.has(type);
|
|
76999
|
+
}
|
|
77000
|
+
/** Reads `element.altText` / `element.title` without a per-type cast. */
|
|
77001
|
+
function readStringField(element, field) {
|
|
77002
|
+
const value = element[field];
|
|
77003
|
+
return typeof value === 'string' ? value : '';
|
|
77004
|
+
}
|
|
77005
|
+
/**
|
|
77006
|
+
* Computes the alt-text / title field descriptor for `element`. See
|
|
77007
|
+
* {@link NonVisualDescriptionFields}.
|
|
77008
|
+
*/
|
|
77009
|
+
function getNonVisualDescriptionFields(element) {
|
|
77010
|
+
const showAltText = supportsAltTextField(element.type);
|
|
77011
|
+
const showTitle = supportsTitleField(element.type);
|
|
77012
|
+
return {
|
|
77013
|
+
showAltText,
|
|
77014
|
+
showTitle,
|
|
77015
|
+
altText: showAltText ? readStringField(element, 'altText') : '',
|
|
77016
|
+
title: showTitle ? readStringField(element, 'title') : '',
|
|
77017
|
+
};
|
|
77018
|
+
}
|
|
77019
|
+
|
|
76211
77020
|
/**
|
|
76212
77021
|
* Which slide element does a pointer event select?
|
|
76213
77022
|
*
|
|
@@ -82543,6 +83352,94 @@ function isEncryptedDeckBytes(bytes) {
|
|
|
82543
83352
|
return detectFileFormat(buffer).encrypted;
|
|
82544
83353
|
}
|
|
82545
83354
|
|
|
83355
|
+
/**
|
|
83356
|
+
* Apply a whole-map replacement (an edit to one style's fill/text/borders/
|
|
83357
|
+
* cell3D facet via `applyTableStyleFieldEdit`, or a brand-new style added via
|
|
83358
|
+
* `createTableStyleEntry` + `addTableStyleToMap`) coming from the editor's
|
|
83359
|
+
* `onStyleMapChange` callback.
|
|
83360
|
+
*/
|
|
83361
|
+
function applyTableStyleMapChange(state, nextMap) {
|
|
83362
|
+
return {
|
|
83363
|
+
tableStyleMap: nextMap,
|
|
83364
|
+
tableStylesToDelete: state.tableStylesToDelete.filter((id) => !(id in nextMap)),
|
|
83365
|
+
};
|
|
83366
|
+
}
|
|
83367
|
+
/**
|
|
83368
|
+
* Apply a style deletion coming from the editor's `onDeleteStyle` callback:
|
|
83369
|
+
* removes the entry from the map and records the id for save-time removal
|
|
83370
|
+
* from `ppt/tableStyles.xml`. Safe to call more than once for the same id.
|
|
83371
|
+
*/
|
|
83372
|
+
function applyTableStyleDelete(state, styleId) {
|
|
83373
|
+
const nextMap = { ...(state.tableStyleMap ?? {}) };
|
|
83374
|
+
delete nextMap[styleId];
|
|
83375
|
+
return {
|
|
83376
|
+
tableStyleMap: nextMap,
|
|
83377
|
+
tableStylesToDelete: state.tableStylesToDelete.includes(styleId)
|
|
83378
|
+
? [...state.tableStylesToDelete]
|
|
83379
|
+
: [...state.tableStylesToDelete, styleId],
|
|
83380
|
+
};
|
|
83381
|
+
}
|
|
83382
|
+
/**
|
|
83383
|
+
* Pick the three `ppt/tableStyles.xml` save option fields off a viewer
|
|
83384
|
+
* state's table-style pieces, for spreading into every
|
|
83385
|
+
* `handler.save(...)` / `saveDeckWithPassword(...)` options object. Omits a
|
|
83386
|
+
* field entirely (rather than passing it as `undefined`) when there is
|
|
83387
|
+
* nothing to say, matching every other optional save-option picker in this
|
|
83388
|
+
* module.
|
|
83389
|
+
*/
|
|
83390
|
+
function tableStyleSaveOptions(state) {
|
|
83391
|
+
return {
|
|
83392
|
+
...(state.tableStyleMap ? { tableStyles: state.tableStyleMap } : {}),
|
|
83393
|
+
...(state.tableStylesDefaultId ? { tableStylesDefaultId: state.tableStylesDefaultId } : {}),
|
|
83394
|
+
...(state.tableStylesToDelete.length > 0
|
|
83395
|
+
? { tableStylesToDelete: [...state.tableStylesToDelete] }
|
|
83396
|
+
: {}),
|
|
83397
|
+
};
|
|
83398
|
+
}
|
|
83399
|
+
/**
|
|
83400
|
+
* The table-data patch to apply when the table-style DEFINITION editor's
|
|
83401
|
+
* "create new style" action (or the style gallery's "pick a style") assigns
|
|
83402
|
+
* `styleId` to the table being edited. A single-key object so every binding
|
|
83403
|
+
* spreads it through the exact same `updateTableData(...)` /
|
|
83404
|
+
* `onUpdateElement(...)` path the style gallery already uses, rather than
|
|
83405
|
+
* hand-rolling `{ tableStyleId: styleId }` five times.
|
|
83406
|
+
*/
|
|
83407
|
+
function tableStyleAssignmentUpdate(styleId) {
|
|
83408
|
+
return { tableStyleId: styleId };
|
|
83409
|
+
}
|
|
83410
|
+
|
|
83411
|
+
/**
|
|
83412
|
+
* Assemble the full `PptxHandlerSaveOptions` for a binding's main save path.
|
|
83413
|
+
* Array-valued fields are omitted (not passed as an empty array) when empty,
|
|
83414
|
+
* matching every binding's pre-existing convention and the option docs on
|
|
83415
|
+
* `PptxHandlerSaveOptions` itself (an omitted field round-trips the original
|
|
83416
|
+
* part verbatim; an empty array would instead clear it).
|
|
83417
|
+
*/
|
|
83418
|
+
function buildDeckSaveOptions(state) {
|
|
83419
|
+
return {
|
|
83420
|
+
headerFooter: state.headerFooter,
|
|
83421
|
+
presentationProperties: state.presentationProperties,
|
|
83422
|
+
viewProperties: state.viewProperties,
|
|
83423
|
+
customShows: state.customShows.length > 0 ? [...state.customShows] : undefined,
|
|
83424
|
+
sections: state.sections.length > 0 ? [...state.sections] : undefined,
|
|
83425
|
+
coreProperties: state.coreProperties,
|
|
83426
|
+
appProperties: state.appProperties,
|
|
83427
|
+
customProperties: state.customProperties.length > 0 ? [...state.customProperties] : undefined,
|
|
83428
|
+
tags: state.tagCollections.length > 0 ? [...state.tagCollections] : undefined,
|
|
83429
|
+
slideMasters: state.slideMasters ? [...state.slideMasters] : [],
|
|
83430
|
+
notesMaster: state.notesMaster,
|
|
83431
|
+
handoutMaster: state.handoutMaster,
|
|
83432
|
+
slideSize: state.slideSize,
|
|
83433
|
+
outputFormat: state.outputFormat,
|
|
83434
|
+
...tableStyleSaveOptions({
|
|
83435
|
+
tableStyleMap: state.tableStyleMap,
|
|
83436
|
+
tableStylesDefaultId: state.tableStylesDefaultId,
|
|
83437
|
+
tableStylesToDelete: state.tableStylesToDelete,
|
|
83438
|
+
}),
|
|
83439
|
+
...embeddedFontSaveOptions(state.embedFonts ?? true),
|
|
83440
|
+
};
|
|
83441
|
+
}
|
|
83442
|
+
|
|
82546
83443
|
const DEFAULT_VIEWER_PREFERENCES = {
|
|
82547
83444
|
autoSave: true,
|
|
82548
83445
|
spellCheck: false,
|
|
@@ -84598,6 +85495,9 @@ function carryBuildState(state) {
|
|
|
84598
85495
|
if (state.diagramReveal) {
|
|
84599
85496
|
carried.diagramReveal = state.diagramReveal;
|
|
84600
85497
|
}
|
|
85498
|
+
if (state.textStyle) {
|
|
85499
|
+
carried.textStyle = state.textStyle;
|
|
85500
|
+
}
|
|
84601
85501
|
return carried;
|
|
84602
85502
|
}
|
|
84603
85503
|
/**
|
|
@@ -84642,12 +85542,14 @@ function applyAnimationGroupSteps(group, ctx) {
|
|
|
84642
85542
|
}
|
|
84643
85543
|
const current = next.get(step.elementId);
|
|
84644
85544
|
const shouldBeVisible = step.presetClass === 'exit' ? (current?.visible ?? true) : true;
|
|
85545
|
+
const carried = carryBuildState(current);
|
|
84645
85546
|
next.set(step.elementId, {
|
|
84646
|
-
...
|
|
85547
|
+
...carried,
|
|
84647
85548
|
visible: shouldBeVisible,
|
|
84648
85549
|
cssAnimation: step.cssAnimation,
|
|
84649
85550
|
animatesFill: step.colorTargets?.includes('fill') ? true : undefined,
|
|
84650
85551
|
animatesStroke: step.colorTargets?.includes('stroke') ? true : undefined,
|
|
85552
|
+
textStyle: mergeTextStyleOnStart(carried.textStyle, step.textStyle),
|
|
84651
85553
|
});
|
|
84652
85554
|
}
|
|
84653
85555
|
return next;
|
|
@@ -84668,11 +85570,14 @@ function applyAnimationGroupSteps(group, ctx) {
|
|
|
84668
85570
|
? false
|
|
84669
85571
|
: (current?.visible ?? true);
|
|
84670
85572
|
// `p:cTn/@fill="hold"`/`"freeze"`: keep the CSS animation attached so
|
|
84671
|
-
// its final frame persists instead of reverting on cleanup.
|
|
85573
|
+
// its final frame persists instead of reverting on cleanup. A
|
|
85574
|
+
// font-style emphasis's text-style override follows the SAME flag.
|
|
85575
|
+
const carried = carryBuildState(current);
|
|
84672
85576
|
next.set(step.elementId, {
|
|
84673
|
-
...
|
|
85577
|
+
...carried,
|
|
84674
85578
|
visible: visibleAfter,
|
|
84675
85579
|
cssAnimation: step.holdEndState ? step.cssAnimation : undefined,
|
|
85580
|
+
textStyle: resolveTextStyleOnCleanup(carried.textStyle, step.textStyle, step.holdEndState),
|
|
84676
85581
|
});
|
|
84677
85582
|
return next;
|
|
84678
85583
|
});
|
|
@@ -86037,6 +86942,315 @@ function mruColorsPatch(recent) {
|
|
|
86037
86942
|
return { mruColors: dedupeAndCap(normalized) };
|
|
86038
86943
|
}
|
|
86039
86944
|
|
|
86945
|
+
/**
|
|
86946
|
+
* Every editable part, in the display order PowerPoint's own "Modify Table
|
|
86947
|
+
* Style" dialog uses (structural regions grouped, background last) - NOT
|
|
86948
|
+
* `TABLE_STYLE_PART_SEQUENCE`'s order, which exists to answer "which section
|
|
86949
|
+
* wins on a given cell" rather than "what order to list them in a picker".
|
|
86950
|
+
*/
|
|
86951
|
+
const TABLE_STYLE_EDITOR_PARTS = [
|
|
86952
|
+
{ id: 'wholeTbl', labelKey: 'pptx.tableStyleEditor.part.wholeTbl' },
|
|
86953
|
+
{ id: 'firstRow', labelKey: 'pptx.tableStyleEditor.part.firstRow' },
|
|
86954
|
+
{ id: 'lastRow', labelKey: 'pptx.tableStyleEditor.part.lastRow' },
|
|
86955
|
+
{ id: 'firstCol', labelKey: 'pptx.tableStyleEditor.part.firstCol' },
|
|
86956
|
+
{ id: 'lastCol', labelKey: 'pptx.tableStyleEditor.part.lastCol' },
|
|
86957
|
+
{ id: 'band1H', labelKey: 'pptx.tableStyleEditor.part.band1H' },
|
|
86958
|
+
{ id: 'band2H', labelKey: 'pptx.tableStyleEditor.part.band2H' },
|
|
86959
|
+
{ id: 'band1V', labelKey: 'pptx.tableStyleEditor.part.band1V' },
|
|
86960
|
+
{ id: 'band2V', labelKey: 'pptx.tableStyleEditor.part.band2V' },
|
|
86961
|
+
{ id: 'neCell', labelKey: 'pptx.tableStyleEditor.part.neCell' },
|
|
86962
|
+
{ id: 'nwCell', labelKey: 'pptx.tableStyleEditor.part.nwCell' },
|
|
86963
|
+
{ id: 'seCell', labelKey: 'pptx.tableStyleEditor.part.seCell' },
|
|
86964
|
+
{ id: 'swCell', labelKey: 'pptx.tableStyleEditor.part.swCell' },
|
|
86965
|
+
{ id: 'background', labelKey: 'pptx.tableStyleEditor.part.background' },
|
|
86966
|
+
];
|
|
86967
|
+
/** Whether a part id is one of the 13 real `CT_TableStyle` sections (not the synthetic background). */
|
|
86968
|
+
function isTableStylePartName(id) {
|
|
86969
|
+
return TABLE_STYLE_PART_SEQUENCE.includes(id);
|
|
86970
|
+
}
|
|
86971
|
+
/** The 8 border sides a section's `a:tcStyle/a:tcBdr` can carry (both diagonals included). */
|
|
86972
|
+
const TABLE_STYLE_BORDER_SIDES = [
|
|
86973
|
+
'left',
|
|
86974
|
+
'right',
|
|
86975
|
+
'top',
|
|
86976
|
+
'bottom',
|
|
86977
|
+
'insideH',
|
|
86978
|
+
'insideV',
|
|
86979
|
+
'tl2br',
|
|
86980
|
+
'tr2bl',
|
|
86981
|
+
];
|
|
86982
|
+
/** i18n key for each border side's label. */
|
|
86983
|
+
const TABLE_STYLE_BORDER_SIDE_LABEL_KEYS = {
|
|
86984
|
+
left: 'pptx.tableStyleEditor.side.left',
|
|
86985
|
+
right: 'pptx.tableStyleEditor.side.right',
|
|
86986
|
+
top: 'pptx.tableStyleEditor.side.top',
|
|
86987
|
+
bottom: 'pptx.tableStyleEditor.side.bottom',
|
|
86988
|
+
insideH: 'pptx.tableStyleEditor.side.insideH',
|
|
86989
|
+
insideV: 'pptx.tableStyleEditor.side.insideV',
|
|
86990
|
+
tl2br: 'pptx.tableStyleEditor.side.tl2br',
|
|
86991
|
+
tr2bl: 'pptx.tableStyleEditor.side.tr2bl',
|
|
86992
|
+
};
|
|
86993
|
+
/** OOXML `a:prstDash@val` choices offered by the dash picker. */
|
|
86994
|
+
const TABLE_STYLE_DASH_PRESETS = [
|
|
86995
|
+
'solid',
|
|
86996
|
+
'dot',
|
|
86997
|
+
'dash',
|
|
86998
|
+
'lgDash',
|
|
86999
|
+
'dashDot',
|
|
87000
|
+
'lgDashDot',
|
|
87001
|
+
'lgDashDotDot',
|
|
87002
|
+
'sysDash',
|
|
87003
|
+
'sysDot',
|
|
87004
|
+
'sysDashDot',
|
|
87005
|
+
'sysDashDotDot',
|
|
87006
|
+
];
|
|
87007
|
+
|
|
87008
|
+
const DEFAULT_FILL_HEX = '#ffffff';
|
|
87009
|
+
const DEFAULT_TEXT_HEX = '#000000';
|
|
87010
|
+
const DEFAULT_BORDER_HEX = '#808080';
|
|
87011
|
+
/** Resolve a `ParsedTableStyleFill` (or a border's colour choice) to a paintable colour + ref. */
|
|
87012
|
+
function fillToColor(fill, themeColorMap, fallbackHex) {
|
|
87013
|
+
if (!fill) {
|
|
87014
|
+
return { hex: fallbackHex, ref: undefined };
|
|
87015
|
+
}
|
|
87016
|
+
if (fill.schemeColor) {
|
|
87017
|
+
const ref = {
|
|
87018
|
+
scheme: fill.schemeColor,
|
|
87019
|
+
tint: fill.tint,
|
|
87020
|
+
shade: fill.shade,
|
|
87021
|
+
};
|
|
87022
|
+
return { hex: resolveThemeColorRef(ref, themeColorMap) ?? fallbackHex, ref };
|
|
87023
|
+
}
|
|
87024
|
+
if (fill.color) {
|
|
87025
|
+
return { hex: fill.color, ref: undefined };
|
|
87026
|
+
}
|
|
87027
|
+
return { hex: fallbackHex, ref: undefined };
|
|
87028
|
+
}
|
|
87029
|
+
/** Bidirectional inverse of {@link fillToColor}: build the `ParsedTableStyleFill` a commit writes. */
|
|
87030
|
+
function colorToFill(hex, ref) {
|
|
87031
|
+
if (ref) {
|
|
87032
|
+
return { schemeColor: ref.scheme, tint: ref.tint, shade: ref.shade };
|
|
87033
|
+
}
|
|
87034
|
+
return { schemeColor: '', color: hex };
|
|
87035
|
+
}
|
|
87036
|
+
function describeFill(fill, themeColorMap) {
|
|
87037
|
+
return {
|
|
87038
|
+
color: fillToColor(fill, themeColorMap, DEFAULT_FILL_HEX),
|
|
87039
|
+
noFill: fill?.noFill ?? false,
|
|
87040
|
+
isSet: fill !== undefined,
|
|
87041
|
+
};
|
|
87042
|
+
}
|
|
87043
|
+
function describeText(text, themeColorMap) {
|
|
87044
|
+
const asFill = text
|
|
87045
|
+
? {
|
|
87046
|
+
schemeColor: text.fontSchemeColor ?? '',
|
|
87047
|
+
tint: text.fontTint,
|
|
87048
|
+
shade: text.fontShade,
|
|
87049
|
+
color: text.fontColor,
|
|
87050
|
+
}
|
|
87051
|
+
: undefined;
|
|
87052
|
+
return {
|
|
87053
|
+
bold: text?.bold ?? false,
|
|
87054
|
+
italic: text?.italic ?? false,
|
|
87055
|
+
underline: text?.underline ?? false,
|
|
87056
|
+
color: fillToColor(asFill, themeColorMap, DEFAULT_TEXT_HEX),
|
|
87057
|
+
isSet: text !== undefined,
|
|
87058
|
+
};
|
|
87059
|
+
}
|
|
87060
|
+
function borderSideColor(border, themeColorMap) {
|
|
87061
|
+
if (border?.fill) {
|
|
87062
|
+
return fillToColor(border.fill, themeColorMap, DEFAULT_BORDER_HEX);
|
|
87063
|
+
}
|
|
87064
|
+
if (border?.color) {
|
|
87065
|
+
return { hex: border.color, ref: undefined };
|
|
87066
|
+
}
|
|
87067
|
+
return { hex: DEFAULT_BORDER_HEX, ref: undefined };
|
|
87068
|
+
}
|
|
87069
|
+
function describeBorders(borders, themeColorMap) {
|
|
87070
|
+
const result = {};
|
|
87071
|
+
for (const side of TABLE_STYLE_BORDER_SIDES) {
|
|
87072
|
+
const border = borders?.[side];
|
|
87073
|
+
result[side] = {
|
|
87074
|
+
color: borderSideColor(border, themeColorMap),
|
|
87075
|
+
width: border?.width ?? 1,
|
|
87076
|
+
dash: border?.dash ?? 'solid',
|
|
87077
|
+
noFill: border?.noFill ?? false,
|
|
87078
|
+
isSet: border !== undefined,
|
|
87079
|
+
};
|
|
87080
|
+
}
|
|
87081
|
+
return result;
|
|
87082
|
+
}
|
|
87083
|
+
function describeCell3D(cell3D) {
|
|
87084
|
+
return {
|
|
87085
|
+
bevelWidth: cell3D?.bevelWidth,
|
|
87086
|
+
bevelHeight: cell3D?.bevelHeight,
|
|
87087
|
+
bevelPreset: cell3D?.bevelPreset,
|
|
87088
|
+
isSet: cell3D !== undefined,
|
|
87089
|
+
};
|
|
87090
|
+
}
|
|
87091
|
+
/**
|
|
87092
|
+
* Build the descriptor for `entry`'s `selectedPart`. Returns `undefined` only
|
|
87093
|
+
* when `entry` itself is `undefined` (no style loaded / selected yet).
|
|
87094
|
+
*/
|
|
87095
|
+
function describeTableStyleEditor(entry, selectedPart, themeColorMap) {
|
|
87096
|
+
if (!entry) {
|
|
87097
|
+
return undefined;
|
|
87098
|
+
}
|
|
87099
|
+
const keyed = entry;
|
|
87100
|
+
const hasTextAndBorders = isTableStylePartName(selectedPart);
|
|
87101
|
+
const fill = selectedPart === 'background'
|
|
87102
|
+
? entry.tableBackground?.fill
|
|
87103
|
+
: keyed[`${selectedPart}Fill`];
|
|
87104
|
+
const text = hasTextAndBorders
|
|
87105
|
+
? keyed[`${selectedPart}Text`]
|
|
87106
|
+
: undefined;
|
|
87107
|
+
const borders = hasTextAndBorders
|
|
87108
|
+
? keyed[`${selectedPart}Borders`]
|
|
87109
|
+
: undefined;
|
|
87110
|
+
const cell3D = hasTextAndBorders
|
|
87111
|
+
? keyed[`${selectedPart}Cell3D`]
|
|
87112
|
+
: undefined;
|
|
87113
|
+
return {
|
|
87114
|
+
styleId: entry.styleId,
|
|
87115
|
+
styleName: entry.styleName ?? '',
|
|
87116
|
+
selectedPart,
|
|
87117
|
+
hasTextAndBorders,
|
|
87118
|
+
fill: describeFill(fill, themeColorMap),
|
|
87119
|
+
text: describeText(text, themeColorMap),
|
|
87120
|
+
borders: describeBorders(borders, themeColorMap),
|
|
87121
|
+
cell3D: describeCell3D(cell3D),
|
|
87122
|
+
};
|
|
87123
|
+
}
|
|
87124
|
+
|
|
87125
|
+
function patchBorderSide(borders, side, patch) {
|
|
87126
|
+
const current = borders?.[side] ?? {};
|
|
87127
|
+
return { ...borders, [side]: { ...current, ...patch } };
|
|
87128
|
+
}
|
|
87129
|
+
/**
|
|
87130
|
+
* Apply one field edit to `entry`'s `part`, returning the new entry plus the
|
|
87131
|
+
* SDK-shaped payload. `part === 'background'` only honours `fillColor` /
|
|
87132
|
+
* `fillNone` (background has no text/borders/cell3D facet); any other edit
|
|
87133
|
+
* kind on the background part is a no-op (returns `entry` unchanged, payload
|
|
87134
|
+
* with no facets set) so a caller does not need to pre-filter by part.
|
|
87135
|
+
*/
|
|
87136
|
+
function applyTableStyleFieldEdit(entry, part, edit) {
|
|
87137
|
+
if (part === 'background') {
|
|
87138
|
+
return applyBackgroundEdit(entry, edit);
|
|
87139
|
+
}
|
|
87140
|
+
const keyed = entry;
|
|
87141
|
+
const fillKey = `${part}Fill`;
|
|
87142
|
+
const textKey = `${part}Text`;
|
|
87143
|
+
const bordersKey = `${part}Borders`;
|
|
87144
|
+
const cell3DKey = `${part}Cell3D`;
|
|
87145
|
+
switch (edit.kind) {
|
|
87146
|
+
case 'fillColor':
|
|
87147
|
+
keyed[fillKey] = colorToFill(edit.hex, edit.ref);
|
|
87148
|
+
break;
|
|
87149
|
+
case 'fillNone': {
|
|
87150
|
+
const current = keyed[fillKey];
|
|
87151
|
+
keyed[fillKey] = { schemeColor: current?.schemeColor ?? '', ...current, noFill: edit.noFill };
|
|
87152
|
+
break;
|
|
87153
|
+
}
|
|
87154
|
+
case 'textBold':
|
|
87155
|
+
keyed[textKey] = {
|
|
87156
|
+
...keyed[textKey],
|
|
87157
|
+
bold: edit.value,
|
|
87158
|
+
};
|
|
87159
|
+
break;
|
|
87160
|
+
case 'textItalic':
|
|
87161
|
+
keyed[textKey] = {
|
|
87162
|
+
...keyed[textKey],
|
|
87163
|
+
italic: edit.value,
|
|
87164
|
+
};
|
|
87165
|
+
break;
|
|
87166
|
+
case 'textUnderline':
|
|
87167
|
+
keyed[textKey] = {
|
|
87168
|
+
...keyed[textKey],
|
|
87169
|
+
underline: edit.value,
|
|
87170
|
+
};
|
|
87171
|
+
break;
|
|
87172
|
+
case 'textColor': {
|
|
87173
|
+
const fill = colorToFill(edit.hex, edit.ref);
|
|
87174
|
+
keyed[textKey] = {
|
|
87175
|
+
...keyed[textKey],
|
|
87176
|
+
fontSchemeColor: fill.schemeColor,
|
|
87177
|
+
fontTint: fill.tint,
|
|
87178
|
+
fontShade: fill.shade,
|
|
87179
|
+
fontColor: fill.color,
|
|
87180
|
+
};
|
|
87181
|
+
break;
|
|
87182
|
+
}
|
|
87183
|
+
case 'borderColor':
|
|
87184
|
+
keyed[bordersKey] = patchBorderSide(keyed[bordersKey], edit.side, { fill: colorToFill(edit.hex, edit.ref), color: edit.ref ? undefined : edit.hex });
|
|
87185
|
+
break;
|
|
87186
|
+
case 'borderWidth':
|
|
87187
|
+
keyed[bordersKey] = patchBorderSide(keyed[bordersKey], edit.side, { width: edit.width });
|
|
87188
|
+
break;
|
|
87189
|
+
case 'borderDash':
|
|
87190
|
+
keyed[bordersKey] = patchBorderSide(keyed[bordersKey], edit.side, { dash: edit.dash });
|
|
87191
|
+
break;
|
|
87192
|
+
case 'borderNone':
|
|
87193
|
+
keyed[bordersKey] = patchBorderSide(keyed[bordersKey], edit.side, { noFill: edit.noFill });
|
|
87194
|
+
break;
|
|
87195
|
+
case 'cell3DBevelWidth':
|
|
87196
|
+
keyed[cell3DKey] = {
|
|
87197
|
+
...keyed[cell3DKey],
|
|
87198
|
+
bevelWidth: edit.value,
|
|
87199
|
+
};
|
|
87200
|
+
break;
|
|
87201
|
+
case 'cell3DBevelHeight':
|
|
87202
|
+
keyed[cell3DKey] = {
|
|
87203
|
+
...keyed[cell3DKey],
|
|
87204
|
+
bevelHeight: edit.value,
|
|
87205
|
+
};
|
|
87206
|
+
break;
|
|
87207
|
+
case 'cell3DBevelPreset':
|
|
87208
|
+
keyed[cell3DKey] = {
|
|
87209
|
+
...keyed[cell3DKey],
|
|
87210
|
+
bevelPreset: edit.value,
|
|
87211
|
+
};
|
|
87212
|
+
break;
|
|
87213
|
+
}
|
|
87214
|
+
const nextEntry = keyed;
|
|
87215
|
+
return {
|
|
87216
|
+
entry: nextEntry,
|
|
87217
|
+
payload: {
|
|
87218
|
+
styleId: entry.styleId,
|
|
87219
|
+
section: part,
|
|
87220
|
+
...(isTableStylePartName(part)
|
|
87221
|
+
? {
|
|
87222
|
+
fill: keyed[fillKey],
|
|
87223
|
+
text: keyed[textKey],
|
|
87224
|
+
borders: keyed[bordersKey],
|
|
87225
|
+
cell3D: keyed[cell3DKey],
|
|
87226
|
+
}
|
|
87227
|
+
: {}),
|
|
87228
|
+
},
|
|
87229
|
+
};
|
|
87230
|
+
}
|
|
87231
|
+
function applyBackgroundEdit(entry, edit) {
|
|
87232
|
+
const current = entry.tableBackground;
|
|
87233
|
+
let nextBackground = current;
|
|
87234
|
+
if (edit.kind === 'fillColor') {
|
|
87235
|
+
nextBackground = { ...current, fill: colorToFill(edit.hex, edit.ref), fillRef: undefined };
|
|
87236
|
+
}
|
|
87237
|
+
else if (edit.kind === 'fillNone') {
|
|
87238
|
+
nextBackground = {
|
|
87239
|
+
...current,
|
|
87240
|
+
fill: {
|
|
87241
|
+
schemeColor: current?.fill?.schemeColor ?? '',
|
|
87242
|
+
...current?.fill,
|
|
87243
|
+
noFill: edit.noFill,
|
|
87244
|
+
},
|
|
87245
|
+
};
|
|
87246
|
+
}
|
|
87247
|
+
const nextEntry = { ...entry, tableBackground: nextBackground };
|
|
87248
|
+
return {
|
|
87249
|
+
entry: nextEntry,
|
|
87250
|
+
payload: { styleId: entry.styleId, section: 'background' },
|
|
87251
|
+
};
|
|
87252
|
+
}
|
|
87253
|
+
|
|
86040
87254
|
/**
|
|
86041
87255
|
* Framework-agnostic rendering & editing helpers shared by the React, Vue, and
|
|
86042
87256
|
* Angular `pptx-viewer` bindings. Pure TypeScript (no framework imports) — each
|
|
@@ -89517,6 +90731,26 @@ function resetAiSdkCache() {
|
|
|
89517
90731
|
cached = undefined;
|
|
89518
90732
|
}
|
|
89519
90733
|
|
|
90734
|
+
/**
|
|
90735
|
+
* deckDataFieldChanged: structural-equality check used by every binding's AI
|
|
90736
|
+
* bridge `applyDeckData()` to decide whether a top-level `PptxData` field
|
|
90737
|
+
* changed before committing it back through the binding's own history/write
|
|
90738
|
+
* path.
|
|
90739
|
+
*
|
|
90740
|
+
* Before this module existed, React, Vue, Angular, Svelte and Vanilla each
|
|
90741
|
+
* declared the identical `const differs = (a, b) => JSON.stringify(a) !==
|
|
90742
|
+
* JSON.stringify(b)` locally inside their `useAiBridge` / `ai-bridge`
|
|
90743
|
+
* modules: a pure helper with no framework imports, duplicated five times
|
|
90744
|
+
* (the exact Rule 2 extraction trigger in CLAUDE.md). Bindings should import
|
|
90745
|
+
* this instead of re-declaring their own copy.
|
|
90746
|
+
*
|
|
90747
|
+
* @module ai/deck-data-diff
|
|
90748
|
+
*/
|
|
90749
|
+
/** True when `a` and `b` are not structurally (deep-value) equal. */
|
|
90750
|
+
function deckDataFieldChanged(a, b) {
|
|
90751
|
+
return JSON.stringify(a) !== JSON.stringify(b);
|
|
90752
|
+
}
|
|
90753
|
+
|
|
89520
90754
|
/**
|
|
89521
90755
|
* Host-facing configuration types for the framework-agnostic AI assistant, plus
|
|
89522
90756
|
* {@link resolveChatTransport}, which turns a declarative {@link PptxAiConnection}
|
|
@@ -91142,7 +92376,7 @@ function createLocalStorageBackend(namespace) {
|
|
|
91142
92376
|
/** Try IndexedDB first; fall back to localStorage on any failure. */
|
|
91143
92377
|
async function resolveBackend(dbName, namespace) {
|
|
91144
92378
|
try {
|
|
91145
|
-
const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-
|
|
92379
|
+
const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-BHSiNfjU.mjs');
|
|
91146
92380
|
const db = await openChatDb(dbName);
|
|
91147
92381
|
return createIdbBackend(db);
|
|
91148
92382
|
}
|
|
@@ -92416,9 +93650,13 @@ function createAngularAiBridge(deps) {
|
|
|
92416
93650
|
customProperties: [...deps.getCustomProperties()],
|
|
92417
93651
|
coreProperties: deps.getCoreProperties(),
|
|
92418
93652
|
appProperties: deps.getAppProperties(),
|
|
93653
|
+
viewProperties: deps.getViewProperties(),
|
|
93654
|
+
tableStyleMap: deps.getTableStyleMap(),
|
|
93655
|
+
tableStylesDefaultId: deps.getTableStylesDefaultId(),
|
|
93656
|
+
tags: [...deps.getTagCollections()],
|
|
92419
93657
|
};
|
|
92420
93658
|
};
|
|
92421
|
-
const differs =
|
|
93659
|
+
const differs = deckDataFieldChanged;
|
|
92422
93660
|
return {
|
|
92423
93661
|
getDeckMeta() {
|
|
92424
93662
|
const slides = deps.getSlides();
|
|
@@ -92490,6 +93728,19 @@ function createAngularAiBridge(deps) {
|
|
|
92490
93728
|
if (differs(before.appProperties, after.appProperties)) {
|
|
92491
93729
|
deps.setAppProperties(after.appProperties);
|
|
92492
93730
|
}
|
|
93731
|
+
if (differs(before.viewProperties, after.viewProperties)) {
|
|
93732
|
+
deps.setViewProperties(after.viewProperties);
|
|
93733
|
+
}
|
|
93734
|
+
if (differs(before.tableStyleMap, after.tableStyleMap)) {
|
|
93735
|
+
deps.setTableStyleMap(after.tableStyleMap);
|
|
93736
|
+
}
|
|
93737
|
+
if (differs(before.tableStylesDefaultId, after.tableStylesDefaultId)) {
|
|
93738
|
+
deps.setTableStylesDefaultId(after.tableStylesDefaultId);
|
|
93739
|
+
}
|
|
93740
|
+
const nextTags = after.tags ?? before.tags ?? [];
|
|
93741
|
+
if (differs(before.tags, nextTags)) {
|
|
93742
|
+
deps.setTagCollections(nextTags);
|
|
93743
|
+
}
|
|
92493
93744
|
},
|
|
92494
93745
|
getFocusedTargets() {
|
|
92495
93746
|
return (deps.getFocusedTargets?.() ?? [{ kind: 'slide', slideIndex: deps.getActiveSlideIndex() }]);
|
|
@@ -94497,12 +95748,17 @@ const WRITE_BACK_DEBOUNCE_MS = 5_000;
|
|
|
94497
95748
|
* Serialize the current Y.Doc slide state (with the separated master/layout
|
|
94498
95749
|
* template elements merged back) into `.pptx` bytes. `sourceBytes` seeds the
|
|
94499
95750
|
* handler so package parts the CRDT does not carry (media, fonts, rels) survive.
|
|
95751
|
+
*
|
|
95752
|
+
* `saveOptions` carries the session-level save options (view properties,
|
|
95753
|
+
* table styles, tags, deck properties, ...) built the same way as the
|
|
95754
|
+
* Save/Export path (`buildDeckSaveOptions`). Without it the write-back
|
|
95755
|
+
* dropped every session-level edit outside `slides`.
|
|
94500
95756
|
*/
|
|
94501
|
-
async function serializeWriteBack(ydoc, sourceBytes, templateElements) {
|
|
95757
|
+
async function serializeWriteBack(ydoc, sourceBytes, templateElements, saveOptions) {
|
|
94502
95758
|
const handler = new PptxHandler();
|
|
94503
95759
|
await handler.load(sourceBytes.buffer);
|
|
94504
95760
|
const slides = buildSaveSlides(readSlidesFromYDoc(ydoc), templateElements);
|
|
94505
|
-
return handler.save(slides);
|
|
95761
|
+
return handler.save(slides, saveOptions);
|
|
94506
95762
|
}
|
|
94507
95763
|
/**
|
|
94508
95764
|
* Debounced elected-writer write-back. Only the session `owner` with an
|
|
@@ -94513,7 +95769,7 @@ class WriteBackScheduler {
|
|
|
94513
95769
|
constructor() {
|
|
94514
95770
|
this.timer = null;
|
|
94515
95771
|
}
|
|
94516
|
-
schedule(config, ydoc, getSourceBytes, getTemplateElements) {
|
|
95772
|
+
schedule(config, ydoc, getSourceBytes, getTemplateElements, getSaveOptions) {
|
|
94517
95773
|
if (!config?.onWriteBack || config.role !== 'owner' || !ydoc) {
|
|
94518
95774
|
return;
|
|
94519
95775
|
}
|
|
@@ -94525,7 +95781,7 @@ class WriteBackScheduler {
|
|
|
94525
95781
|
if (!bytes || !config.onWriteBack) {
|
|
94526
95782
|
return;
|
|
94527
95783
|
}
|
|
94528
|
-
void serializeWriteBack(ydoc, bytes, getTemplateElements?.() ?? {})
|
|
95784
|
+
void serializeWriteBack(ydoc, bytes, getTemplateElements?.() ?? {}, getSaveOptions?.())
|
|
94529
95785
|
.then((out) => config.onWriteBack?.(out))
|
|
94530
95786
|
.catch(() => {
|
|
94531
95787
|
/* non-fatal */
|
|
@@ -94609,6 +95865,7 @@ class CollaborationService {
|
|
|
94609
95865
|
this.canvasHeight = DEFAULT_CANVAS_BOUND;
|
|
94610
95866
|
this.getSourceBytes = null;
|
|
94611
95867
|
this.getTemplateElements = null;
|
|
95868
|
+
this.getSaveOptions = null;
|
|
94612
95869
|
this.currentConfig = null;
|
|
94613
95870
|
this.lastConfig = null;
|
|
94614
95871
|
this.lastOptions = {};
|
|
@@ -94681,6 +95938,7 @@ class CollaborationService {
|
|
|
94681
95938
|
this.canvasHeight = options.canvasHeight ?? DEFAULT_CANVAS_BOUND;
|
|
94682
95939
|
this.getSourceBytes = options.getSourceBytes ?? null;
|
|
94683
95940
|
this.getTemplateElements = options.getTemplateElements ?? null;
|
|
95941
|
+
this.getSaveOptions = options.getSaveOptions ?? null;
|
|
94684
95942
|
this.currentConfig = config;
|
|
94685
95943
|
this.activeRole.set(config.role);
|
|
94686
95944
|
this.status.set('connecting');
|
|
@@ -94787,7 +96045,7 @@ class CollaborationService {
|
|
|
94787
96045
|
this.followedClientId.set(clientId);
|
|
94788
96046
|
}
|
|
94789
96047
|
scheduleWriteBack() {
|
|
94790
|
-
this.writeBack.schedule(this.currentConfig, this.session?.ydoc ?? null, this.getSourceBytes, this.getTemplateElements);
|
|
96048
|
+
this.writeBack.schedule(this.currentConfig, this.session?.ydoc ?? null, this.getSourceBytes, this.getTemplateElements, this.getSaveOptions);
|
|
94791
96049
|
}
|
|
94792
96050
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CollaborationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
94793
96051
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CollaborationService }); }
|
|
@@ -96213,6 +97471,16 @@ class LoadContentService {
|
|
|
96213
97471
|
/** Parsed table-style definitions from `ppt/tableStyles.xml` (banding/diagonals). */
|
|
96214
97472
|
this.tableStyleMap = signal(undefined, /* @ts-ignore */
|
|
96215
97473
|
...(ngDevMode ? [{ debugName: "tableStyleMap" }] : /* istanbul ignore next */ []));
|
|
97474
|
+
/** `ppt/tableStyles.xml`'s `<a:tblStyleLst @def>` default style GUID. */
|
|
97475
|
+
this.tableStylesDefaultId = signal(undefined, /* @ts-ignore */
|
|
97476
|
+
...(ngDevMode ? [{ debugName: "tableStylesDefaultId" }] : /* istanbul ignore next */ []));
|
|
97477
|
+
/**
|
|
97478
|
+
* Style GUIDs deleted from `tableStyleMap` via the table style editor,
|
|
97479
|
+
* pending removal from `ppt/tableStyles.xml` on the next save. See
|
|
97480
|
+
* `tableStyleSaveOptions` / `applyTableStyleDelete` in `pptx-viewer-shared`.
|
|
97481
|
+
*/
|
|
97482
|
+
this.tableStylesToDelete = signal([], /* @ts-ignore */
|
|
97483
|
+
...(ngDevMode ? [{ debugName: "tableStylesToDelete" }] : /* istanbul ignore next */ []));
|
|
96216
97484
|
/** Slide masters (for placeholder/background resolution). */
|
|
96217
97485
|
this.slideMasters = signal([], /* @ts-ignore */
|
|
96218
97486
|
...(ngDevMode ? [{ debugName: "slideMasters" }] : /* istanbul ignore next */ []));
|
|
@@ -96376,28 +97644,35 @@ class LoadContentService {
|
|
|
96376
97644
|
// Shared decision (see `deck-save-encryption` in `pptx-viewer-shared`): a
|
|
96377
97645
|
// password set in the protection dialog routes through `saveEncrypted`, so
|
|
96378
97646
|
// the produced file is a real encrypted OLE2 container.
|
|
96379
|
-
return saveDeckWithPassword(this.handler, [...slides], {
|
|
97647
|
+
return saveDeckWithPassword(this.handler, [...slides], buildDeckSaveOptions({
|
|
96380
97648
|
headerFooter: this.headerFooter(),
|
|
96381
97649
|
presentationProperties: this.presentationProperties(),
|
|
96382
97650
|
slideMasters: this.slideMasters(),
|
|
96383
97651
|
notesMaster: this.notesMaster(),
|
|
96384
97652
|
handoutMaster: this.handoutMaster(),
|
|
96385
|
-
sections
|
|
97653
|
+
sections,
|
|
96386
97654
|
// Without this the Custom Shows dialog was write-only: shows created
|
|
96387
97655
|
// in it never reached `p:custShowLst`, and a deck that arrived with
|
|
96388
97656
|
// shows lost them on save.
|
|
96389
|
-
customShows
|
|
97657
|
+
customShows,
|
|
96390
97658
|
// The only route a slide-size edit has into the saved `p:sldSz`.
|
|
96391
97659
|
slideSize: this.slideSizeSelection().size,
|
|
96392
97660
|
coreProperties: this.coreProperties(),
|
|
96393
97661
|
appProperties: this.appProperties(),
|
|
96394
|
-
customProperties
|
|
96395
|
-
|
|
97662
|
+
customProperties,
|
|
97663
|
+
tagCollections: tags,
|
|
96396
97664
|
outputFormat,
|
|
97665
|
+
// Without this core falls back to `viewProps.xml` as it was FIRST
|
|
97666
|
+
// opened, so every View-ribbon grid/guide/snap toggle silently
|
|
97667
|
+
// reverted at the file boundary.
|
|
97668
|
+
viewProperties: this.viewProperties(),
|
|
97669
|
+
tableStyleMap: this.tableStyleMap(),
|
|
97670
|
+
tableStylesDefaultId: this.tableStylesDefaultId(),
|
|
97671
|
+
tableStylesToDelete: this.tableStylesToDelete(),
|
|
96397
97672
|
// The Fonts panel's toggle used to move and change nothing; it now
|
|
96398
97673
|
// decides whether the deck's embedded font data survives the save.
|
|
96399
|
-
|
|
96400
|
-
}, password);
|
|
97674
|
+
embedFonts: this.embedFonts(),
|
|
97675
|
+
}), password);
|
|
96401
97676
|
}
|
|
96402
97677
|
/** Parse the supplied `.pptx` bytes into the reactive signals. */
|
|
96403
97678
|
async load(raw) {
|
|
@@ -96538,6 +97813,8 @@ class LoadContentService {
|
|
|
96538
97813
|
this.theme.set(parsed.theme);
|
|
96539
97814
|
this.themeColorMap.set(parsed.themeColorMap);
|
|
96540
97815
|
this.tableStyleMap.set(nextTableStyleMap);
|
|
97816
|
+
this.tableStylesDefaultId.set(parsed.tableStylesDefaultId);
|
|
97817
|
+
this.tableStylesToDelete.set([]);
|
|
96541
97818
|
this.slideMasters.set(parsed.slideMasters ?? []);
|
|
96542
97819
|
this.notesMaster.set(parsed.notesMaster);
|
|
96543
97820
|
this.handoutMaster.set(parsed.handoutMaster);
|
|
@@ -102158,7 +103435,21 @@ class ChartRendererComponent {
|
|
|
102158
103435
|
[attr.fill]="vm().titleStyle?.fill ?? '#1e293b'"
|
|
102159
103436
|
data-chart-part="title"
|
|
102160
103437
|
>
|
|
102161
|
-
|
|
103438
|
+
@if (vm().titleRunSpans; as titleRunSpans) {
|
|
103439
|
+
@for (run of titleRunSpans; track $index) {
|
|
103440
|
+
<tspan
|
|
103441
|
+
[attr.font-size]="run.fontSize"
|
|
103442
|
+
[attr.font-weight]="run.fontWeight"
|
|
103443
|
+
[attr.font-style]="run.fontStyle"
|
|
103444
|
+
[attr.font-family]="run.fontFamily"
|
|
103445
|
+
[attr.fill]="run.fill"
|
|
103446
|
+
>
|
|
103447
|
+
{{ run.text }}
|
|
103448
|
+
</tspan>
|
|
103449
|
+
}
|
|
103450
|
+
} @else {
|
|
103451
|
+
{{ vm().title }}
|
|
103452
|
+
}
|
|
102162
103453
|
</text>
|
|
102163
103454
|
}
|
|
102164
103455
|
|
|
@@ -102357,7 +103648,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
102357
103648
|
[attr.fill]="vm().titleStyle?.fill ?? '#1e293b'"
|
|
102358
103649
|
data-chart-part="title"
|
|
102359
103650
|
>
|
|
102360
|
-
|
|
103651
|
+
@if (vm().titleRunSpans; as titleRunSpans) {
|
|
103652
|
+
@for (run of titleRunSpans; track $index) {
|
|
103653
|
+
<tspan
|
|
103654
|
+
[attr.font-size]="run.fontSize"
|
|
103655
|
+
[attr.font-weight]="run.fontWeight"
|
|
103656
|
+
[attr.font-style]="run.fontStyle"
|
|
103657
|
+
[attr.font-family]="run.fontFamily"
|
|
103658
|
+
[attr.fill]="run.fill"
|
|
103659
|
+
>
|
|
103660
|
+
{{ run.text }}
|
|
103661
|
+
</tspan>
|
|
103662
|
+
}
|
|
103663
|
+
} @else {
|
|
103664
|
+
{{ vm().title }}
|
|
103665
|
+
}
|
|
102361
103666
|
</text>
|
|
102362
103667
|
}
|
|
102363
103668
|
|
|
@@ -102789,6 +104094,17 @@ function chartDragCommitData(session, commit) {
|
|
|
102789
104094
|
}
|
|
102790
104095
|
return session.lastData;
|
|
102791
104096
|
}
|
|
104097
|
+
/**
|
|
104098
|
+
* Same gate as {@link chartDragCommitData}, for a pie/radar/stacked mark drag
|
|
104099
|
+
* ({@link ChartMarkDragState} carries the same `moved`/`lastData` shape as the
|
|
104100
|
+
* cartesian value-drag session, just resolved through a different geometry).
|
|
104101
|
+
*/
|
|
104102
|
+
function chartMarkDragCommitData(session, commit) {
|
|
104103
|
+
if (!commit || !session?.moved) {
|
|
104104
|
+
return null;
|
|
104105
|
+
}
|
|
104106
|
+
return session.lastData;
|
|
104107
|
+
}
|
|
102792
104108
|
/**
|
|
102793
104109
|
* Commit an on-canvas chart edit through the editor's normal element-update
|
|
102794
104110
|
* path (the exact channel the inspector uses: one history snapshot per call).
|
|
@@ -103381,6 +104697,12 @@ class ChartElementViewComponent {
|
|
|
103381
104697
|
...(ngDevMode ? [{ debugName: "titleEditor" }] : /* istanbul ignore next */ []));
|
|
103382
104698
|
/** In-flight vertical value drag, or null. */
|
|
103383
104699
|
this.dragSession = null;
|
|
104700
|
+
/**
|
|
104701
|
+
* In-flight pie/doughnut slice, radar vertex, or stacked segment drag, or
|
|
104702
|
+
* null. Runs through a parallel state machine (no single vertical value
|
|
104703
|
+
* axis), never both at once.
|
|
104704
|
+
*/
|
|
104705
|
+
this.markDragSession = null;
|
|
103384
104706
|
/** Local drag preview: rendered instead of the committed data mid-drag. */
|
|
103385
104707
|
this.previewData = signal(null, /* @ts-ignore */
|
|
103386
104708
|
...(ngDevMode ? [{ debugName: "previewData" }] : /* istanbul ignore next */ []));
|
|
@@ -103541,13 +104863,46 @@ class ChartElementViewComponent {
|
|
|
103541
104863
|
if (!chartData || !vm) {
|
|
103542
104864
|
return;
|
|
103543
104865
|
}
|
|
103544
|
-
|
|
103545
|
-
|
|
103546
|
-
|
|
103547
|
-
|
|
103548
|
-
|
|
103549
|
-
|
|
103550
|
-
|
|
104866
|
+
let captured = false;
|
|
104867
|
+
// Pie/doughnut/radar/stacked marks: try the angle/radial/segment drag first.
|
|
104868
|
+
const chartKind = resolveChartKind(chartData.chartType ?? 'bar');
|
|
104869
|
+
if (part.pointIndex !== undefined && chartKind !== 'unsupported') {
|
|
104870
|
+
const markGeometry = buildChartMarkDragGeometry({
|
|
104871
|
+
kind: chartKind,
|
|
104872
|
+
element: this.element(),
|
|
104873
|
+
chartData,
|
|
104874
|
+
categoryLabels: chartData.categories,
|
|
104875
|
+
seriesIndex: part.seriesIndex,
|
|
104876
|
+
pointIndex: part.pointIndex,
|
|
104877
|
+
});
|
|
104878
|
+
const markSession = beginChartMarkDrag({
|
|
104879
|
+
part,
|
|
104880
|
+
geometry: markGeometry,
|
|
104881
|
+
chartData,
|
|
104882
|
+
svgWidth: vm.svgWidth,
|
|
104883
|
+
svgHeight: vm.svgHeight,
|
|
104884
|
+
clientX: event.clientX,
|
|
104885
|
+
clientY: event.clientY,
|
|
104886
|
+
});
|
|
104887
|
+
if (markSession) {
|
|
104888
|
+
this.markDragSession = markSession;
|
|
104889
|
+
captured = true;
|
|
104890
|
+
}
|
|
104891
|
+
}
|
|
104892
|
+
// Clustered bar/line/scatter/bubble: the existing vertical value-axis drag.
|
|
104893
|
+
if (!captured) {
|
|
104894
|
+
const session = beginChartValueDrag({
|
|
104895
|
+
part,
|
|
104896
|
+
viewModel: vm,
|
|
104897
|
+
chartData,
|
|
104898
|
+
clientY: event.clientY,
|
|
104899
|
+
});
|
|
104900
|
+
if (session) {
|
|
104901
|
+
this.dragSession = session;
|
|
104902
|
+
captured = true;
|
|
104903
|
+
}
|
|
104904
|
+
}
|
|
104905
|
+
if (!captured) {
|
|
103551
104906
|
return;
|
|
103552
104907
|
}
|
|
103553
104908
|
event.preventDefault();
|
|
@@ -103559,9 +104914,21 @@ class ChartElementViewComponent {
|
|
|
103559
104914
|
catch {
|
|
103560
104915
|
// Non-fatal: the drag still works while the pointer stays over the chart.
|
|
103561
104916
|
}
|
|
103562
|
-
this.dragSession = session;
|
|
103563
104917
|
}
|
|
103564
104918
|
onPointerMove(event) {
|
|
104919
|
+
const markSession = this.markDragSession;
|
|
104920
|
+
if (markSession) {
|
|
104921
|
+
const rect = this.wrapper()?.nativeElement.querySelector('svg')?.getBoundingClientRect();
|
|
104922
|
+
if (!rect) {
|
|
104923
|
+
return;
|
|
104924
|
+
}
|
|
104925
|
+
const step = advanceChartMarkDrag(markSession, event.clientX, event.clientY, rect);
|
|
104926
|
+
if (step) {
|
|
104927
|
+
this.previewData.set(step.chartData);
|
|
104928
|
+
this.dragValue.set(step.value);
|
|
104929
|
+
}
|
|
104930
|
+
return;
|
|
104931
|
+
}
|
|
103565
104932
|
const session = this.dragSession;
|
|
103566
104933
|
if (!session) {
|
|
103567
104934
|
return;
|
|
@@ -103575,19 +104942,21 @@ class ChartElementViewComponent {
|
|
|
103575
104942
|
}
|
|
103576
104943
|
}
|
|
103577
104944
|
onPointerUp() {
|
|
103578
|
-
if (this.dragSession) {
|
|
104945
|
+
if (this.dragSession || this.markDragSession) {
|
|
103579
104946
|
this.endDrag(true);
|
|
103580
104947
|
}
|
|
103581
104948
|
}
|
|
103582
104949
|
/** Cancel an in-flight value drag with Escape (document-level, like React). */
|
|
103583
104950
|
onEscape() {
|
|
103584
|
-
if (this.dragSession) {
|
|
104951
|
+
if (this.dragSession || this.markDragSession) {
|
|
103585
104952
|
this.endDrag(false);
|
|
103586
104953
|
}
|
|
103587
104954
|
}
|
|
103588
104955
|
endDrag(commit) {
|
|
103589
|
-
const data = chartDragCommitData(this.dragSession, commit)
|
|
104956
|
+
const data = chartDragCommitData(this.dragSession, commit) ??
|
|
104957
|
+
chartMarkDragCommitData(this.markDragSession, commit);
|
|
103590
104958
|
this.dragSession = null;
|
|
104959
|
+
this.markDragSession = null;
|
|
103591
104960
|
this.previewData.set(null);
|
|
103592
104961
|
this.dragValue.set(null);
|
|
103593
104962
|
if (data) {
|
|
@@ -103949,6 +105318,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
103949
105318
|
}]
|
|
103950
105319
|
}], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }], textStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "textStyle", required: false }] }] } });
|
|
103951
105320
|
|
|
105321
|
+
/**
|
|
105322
|
+
* `pptx-dynamic-style`: a `<style>` element whose text follows a signal.
|
|
105323
|
+
*
|
|
105324
|
+
* Angular's template compiler strips every literal `<style>` from a component
|
|
105325
|
+
* template and folds its STATIC text into the component's styles, so both
|
|
105326
|
+
* `<style>{{ css }}</style>` and `<style [textContent]="css">` render nothing
|
|
105327
|
+
* at runtime (the former even trips esbuild's CSS parser on the `{{`). The
|
|
105328
|
+
* other four bindings interpolate into a real `<style>` (Svelte via
|
|
105329
|
+
* `<svelte:element this={'style'}>`, Vue via `<component :is="'style'">`);
|
|
105330
|
+
* this component is Angular's equivalent: it creates the element imperatively
|
|
105331
|
+
* through `Renderer2`, which the compiler never sees, and keeps its
|
|
105332
|
+
* `textContent` in step with the `css` input.
|
|
105333
|
+
*
|
|
105334
|
+
* Used for per-element animation CSS that must live in the document rather
|
|
105335
|
+
* than in component styles: the text-style emphasis override
|
|
105336
|
+
* (`animation-text-style-css.ts`) and the ink replay keyframes.
|
|
105337
|
+
*
|
|
105338
|
+
* @module viewer/dynamic-style.component
|
|
105339
|
+
*/
|
|
105340
|
+
class DynamicStyleComponent {
|
|
105341
|
+
constructor() {
|
|
105342
|
+
/** The stylesheet text; `undefined`/empty removes the `<style>` element. */
|
|
105343
|
+
this.css = input(undefined, /* @ts-ignore */
|
|
105344
|
+
...(ngDevMode ? [{ debugName: "css" }] : /* istanbul ignore next */ []));
|
|
105345
|
+
this.host = inject(ElementRef);
|
|
105346
|
+
this.renderer = inject(Renderer2);
|
|
105347
|
+
effect(() => {
|
|
105348
|
+
const text = this.css();
|
|
105349
|
+
if (!text) {
|
|
105350
|
+
if (this.styleEl) {
|
|
105351
|
+
this.renderer.removeChild(this.host.nativeElement, this.styleEl);
|
|
105352
|
+
this.styleEl = undefined;
|
|
105353
|
+
}
|
|
105354
|
+
return;
|
|
105355
|
+
}
|
|
105356
|
+
if (!this.styleEl) {
|
|
105357
|
+
this.styleEl = this.renderer.createElement('style');
|
|
105358
|
+
this.renderer.appendChild(this.host.nativeElement, this.styleEl);
|
|
105359
|
+
}
|
|
105360
|
+
this.renderer.setProperty(this.styleEl, 'textContent', text);
|
|
105361
|
+
});
|
|
105362
|
+
}
|
|
105363
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DynamicStyleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
105364
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: DynamicStyleComponent, isStandalone: true, selector: "pptx-dynamic-style", inputs: { css: { classPropertyName: "css", publicName: "css", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
105365
|
+
}
|
|
105366
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DynamicStyleComponent, decorators: [{
|
|
105367
|
+
type: Component,
|
|
105368
|
+
args: [{
|
|
105369
|
+
selector: 'pptx-dynamic-style',
|
|
105370
|
+
standalone: true,
|
|
105371
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
105372
|
+
template: '',
|
|
105373
|
+
host: { style: 'display: contents' },
|
|
105374
|
+
}]
|
|
105375
|
+
}], ctorParameters: () => [], propDecorators: { css: [{ type: i0.Input, args: [{ isSignal: true, alias: "css", required: false }] }] } });
|
|
105376
|
+
|
|
103952
105377
|
/**
|
|
103953
105378
|
* ConnectorRendererComponent: Angular port of the Vue `ConnectorRenderer.vue`
|
|
103954
105379
|
* (and the React `ConnectorElementRenderer`, basic subset).
|
|
@@ -104010,6 +105435,14 @@ class ConnectorRendererComponent {
|
|
|
104010
105435
|
*/
|
|
104011
105436
|
this.animationState = input(undefined, /* @ts-ignore */
|
|
104012
105437
|
...(ngDevMode ? [{ debugName: "animationState" }] : /* istanbul ignore next */ []));
|
|
105438
|
+
/**
|
|
105439
|
+
* Scoped `!important` CSS override for an active font-style emphasis effect
|
|
105440
|
+
* (Bold Flash, Bold Reveal, Underline, Change Font Style/Size), built by the
|
|
105441
|
+
* parent `ElementRendererComponent` (`buildTextStyleOverrideCss`) so a
|
|
105442
|
+
* connector's own caption animates the same way a shape's text does.
|
|
105443
|
+
*/
|
|
105444
|
+
this.textStyleOverrideCss = input(undefined, /* @ts-ignore */
|
|
105445
|
+
...(ngDevMode ? [{ debugName: "textStyleOverrideCss" }] : /* istanbul ignore next */ []));
|
|
104013
105446
|
/** All derived geometry, recomputed on every input change. */
|
|
104014
105447
|
this.geo = computed(() => {
|
|
104015
105448
|
const obstacles = this.obstacles();
|
|
@@ -104076,13 +105509,18 @@ class ConnectorRendererComponent {
|
|
|
104076
105509
|
...(ngDevMode ? [{ debugName: "connectorTextStyle" }] : /* istanbul ignore next */ []));
|
|
104077
105510
|
}
|
|
104078
105511
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ConnectorRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
104079
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ConnectorRendererComponent, isStandalone: true, selector: "pptx-connector-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, animationState: { classPropertyName: "animationState", publicName: "animationState", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
105512
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ConnectorRendererComponent, isStandalone: true, selector: "pptx-connector-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, animationState: { classPropertyName: "animationState", publicName: "animationState", isSignal: true, isRequired: false, transformFunction: null }, textStyleOverrideCss: { classPropertyName: "textStyleOverrideCss", publicName: "textStyleOverrideCss", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
104080
105513
|
<div
|
|
104081
105514
|
class="pptx-ng-element pptx-ng-connector"
|
|
104082
105515
|
[style]="wrapperStyle()"
|
|
104083
105516
|
[attr.data-element-id]="elementIdAttr()"
|
|
104084
105517
|
[attr.data-pptx-element]="interactive() || marked() ? 'true' : null"
|
|
104085
105518
|
>
|
|
105519
|
+
<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,
|
|
105520
|
+
Change Font Style/Size) overrides the caption's own inline
|
|
105521
|
+
bold/italic/underline/size, which plain CSS inheritance cannot
|
|
105522
|
+
reach. See animation-text-style-css.ts. -->
|
|
105523
|
+
<pptx-dynamic-style [css]="textStyleOverrideCss()" />
|
|
104086
105524
|
<svg
|
|
104087
105525
|
[attr.width]="geo().svgW"
|
|
104088
105526
|
[attr.height]="geo().svgH"
|
|
@@ -104196,7 +105634,7 @@ class ConnectorRendererComponent {
|
|
|
104196
105634
|
[textStyle]="connectorTextStyle()"
|
|
104197
105635
|
/>
|
|
104198
105636
|
</div>
|
|
104199
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ConnectorTextOverlayComponent, selector: "pptx-connector-text-overlay", inputs: ["text", "segments", "textStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
105637
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ConnectorTextOverlayComponent, selector: "pptx-connector-text-overlay", inputs: ["text", "segments", "textStyle"] }, { kind: "component", type: DynamicStyleComponent, selector: "pptx-dynamic-style", inputs: ["css"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
104200
105638
|
}
|
|
104201
105639
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ConnectorRendererComponent, decorators: [{
|
|
104202
105640
|
type: Component,
|
|
@@ -104204,7 +105642,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
104204
105642
|
selector: 'pptx-connector-renderer',
|
|
104205
105643
|
standalone: true,
|
|
104206
105644
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
104207
|
-
imports: [ConnectorTextOverlayComponent],
|
|
105645
|
+
imports: [ConnectorTextOverlayComponent, DynamicStyleComponent],
|
|
104208
105646
|
template: `
|
|
104209
105647
|
<div
|
|
104210
105648
|
class="pptx-ng-element pptx-ng-connector"
|
|
@@ -104212,6 +105650,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
104212
105650
|
[attr.data-element-id]="elementIdAttr()"
|
|
104213
105651
|
[attr.data-pptx-element]="interactive() || marked() ? 'true' : null"
|
|
104214
105652
|
>
|
|
105653
|
+
<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,
|
|
105654
|
+
Change Font Style/Size) overrides the caption's own inline
|
|
105655
|
+
bold/italic/underline/size, which plain CSS inheritance cannot
|
|
105656
|
+
reach. See animation-text-style-css.ts. -->
|
|
105657
|
+
<pptx-dynamic-style [css]="textStyleOverrideCss()" />
|
|
104215
105658
|
<svg
|
|
104216
105659
|
[attr.width]="geo().svgW"
|
|
104217
105660
|
[attr.height]="geo().svgH"
|
|
@@ -104327,7 +105770,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
104327
105770
|
</div>
|
|
104328
105771
|
`,
|
|
104329
105772
|
}]
|
|
104330
|
-
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], obstacles: [{ type: i0.Input, args: [{ isSignal: true, alias: "obstacles", required: false }] }], canvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasWidth", required: false }] }], canvasHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasHeight", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], marked: [{ type: i0.Input, args: [{ isSignal: true, alias: "marked", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], animationState: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationState", required: false }] }] } });
|
|
105773
|
+
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], obstacles: [{ type: i0.Input, args: [{ isSignal: true, alias: "obstacles", required: false }] }], canvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasWidth", required: false }] }], canvasHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasHeight", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], marked: [{ type: i0.Input, args: [{ isSignal: true, alias: "marked", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], animationState: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationState", required: false }] }], textStyleOverrideCss: [{ type: i0.Input, args: [{ isSignal: true, alias: "textStyleOverrideCss", required: false }] }] } });
|
|
104331
105774
|
|
|
104332
105775
|
/**
|
|
104333
105776
|
* Scalar viewer defaults, shared across the React, Vue, and Angular bindings
|
|
@@ -105205,15 +106648,15 @@ class ContentPartRendererComponent {
|
|
|
105205
106648
|
[attr.data-pptx-element]="markElement() ? 'true' : null"
|
|
105206
106649
|
>
|
|
105207
106650
|
@if (strokes().length > 0) {
|
|
106651
|
+
@if (replay()) {
|
|
106652
|
+
<pptx-dynamic-style [css]="replayKeyframes" />
|
|
106653
|
+
}
|
|
105208
106654
|
<svg
|
|
105209
106655
|
class="pptx-ng-contentpart-svg"
|
|
105210
106656
|
[attr.viewBox]="viewBox()"
|
|
105211
106657
|
preserveAspectRatio="none"
|
|
105212
106658
|
style="width:100%;height:100%;pointer-events:none;display:block"
|
|
105213
106659
|
>
|
|
105214
|
-
@if (replay()) {
|
|
105215
|
-
<style [textContent]="replayKeyframes"></style>
|
|
105216
|
-
}
|
|
105217
106660
|
@for (stroke of strokes(); track stroke.key) {
|
|
105218
106661
|
@if (stroke.nibMarks && stroke.nibMarks.length > 0) {
|
|
105219
106662
|
<g [attr.opacity]="stroke.opacity">
|
|
@@ -105263,11 +106706,11 @@ class ContentPartRendererComponent {
|
|
|
105263
106706
|
</div>
|
|
105264
106707
|
}
|
|
105265
106708
|
</div>
|
|
105266
|
-
`, isInline: true, styles: [".pptx-ng-contentpart-fallback{width:100%;height:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:1px dashed rgba(100,116,139,.6);border-radius:4px;background:#94a3b814}.pptx-ng-contentpart-fallback-label{font-size:11px;font-family:system-ui,sans-serif;color:#64748be6;text-transform:uppercase;letter-spacing:.08em}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
106709
|
+
`, isInline: true, styles: [".pptx-ng-contentpart-fallback{width:100%;height:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:1px dashed rgba(100,116,139,.6);border-radius:4px;background:#94a3b814}.pptx-ng-contentpart-fallback-label{font-size:11px;font-family:system-ui,sans-serif;color:#64748be6;text-transform:uppercase;letter-spacing:.08em}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: DynamicStyleComponent, selector: "pptx-dynamic-style", inputs: ["css"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
105267
106710
|
}
|
|
105268
106711
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ContentPartRendererComponent, decorators: [{
|
|
105269
106712
|
type: Component,
|
|
105270
|
-
args: [{ selector: 'pptx-content-part-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle], template: `
|
|
106713
|
+
args: [{ selector: 'pptx-content-part-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle, DynamicStyleComponent], template: `
|
|
105271
106714
|
<div
|
|
105272
106715
|
class="pptx-ng-element pptx-ng-contentpart"
|
|
105273
106716
|
[ngStyle]="containerStyle()"
|
|
@@ -105275,15 +106718,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
105275
106718
|
[attr.data-pptx-element]="markElement() ? 'true' : null"
|
|
105276
106719
|
>
|
|
105277
106720
|
@if (strokes().length > 0) {
|
|
106721
|
+
@if (replay()) {
|
|
106722
|
+
<pptx-dynamic-style [css]="replayKeyframes" />
|
|
106723
|
+
}
|
|
105278
106724
|
<svg
|
|
105279
106725
|
class="pptx-ng-contentpart-svg"
|
|
105280
106726
|
[attr.viewBox]="viewBox()"
|
|
105281
106727
|
preserveAspectRatio="none"
|
|
105282
106728
|
style="width:100%;height:100%;pointer-events:none;display:block"
|
|
105283
106729
|
>
|
|
105284
|
-
@if (replay()) {
|
|
105285
|
-
<style [textContent]="replayKeyframes"></style>
|
|
105286
|
-
}
|
|
105287
106730
|
@for (stroke of strokes(); track stroke.key) {
|
|
105288
106731
|
@if (stroke.nibMarks && stroke.nibMarks.length > 0) {
|
|
105289
106732
|
<g [attr.opacity]="stroke.opacity">
|
|
@@ -108632,6 +110075,18 @@ class ElementRendererComponent {
|
|
|
108632
110075
|
*/
|
|
108633
110076
|
this.animationState = computed(() => this.playback?.presentationElementStates().get(this.element().id), /* @ts-ignore */
|
|
108634
110077
|
...(ngDevMode ? [{ debugName: "animationState" }] : /* istanbul ignore next */ []));
|
|
110078
|
+
/**
|
|
110079
|
+
* A font-style emphasis effect (Bold Flash, Bold Reveal, Underline, Change
|
|
110080
|
+
* Font Style/Size) overrides the runs' own inline bold/italic/underline/
|
|
110081
|
+
* size, which plain CSS inheritance cannot reach (the runs declare those
|
|
110082
|
+
* unconditionally). See `animation-text-style-css.ts`. NOT gated on
|
|
110083
|
+
* `hasTextProperties`: a table cell, a chart title/label/legend, and a
|
|
110084
|
+
* SmartArt node caption all animate this way too, and shared's selector
|
|
110085
|
+
* already scopes itself to this element's `data-element-id`, which every
|
|
110086
|
+
* branch of the template below carries on its own root.
|
|
110087
|
+
*/
|
|
110088
|
+
this.textStyleOverrideCss = computed(() => buildTextStyleOverrideCss(this.element().id, this.animationState()?.textStyle), /* @ts-ignore */
|
|
110089
|
+
...(ngDevMode ? [{ debugName: "textStyleOverrideCss" }] : /* istanbul ignore next */ []));
|
|
108635
110090
|
/**
|
|
108636
110091
|
* Per-paragraph split for a staged text build (by paragraph / word / letter),
|
|
108637
110092
|
* or `undefined` entries to render the runs normally. PowerPoint's "Animate
|
|
@@ -108806,7 +110261,7 @@ class ElementRendererComponent {
|
|
|
108806
110261
|
return { ...(span.style ?? {}), ...textBuildSpanStyle(span) };
|
|
108807
110262
|
}
|
|
108808
110263
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
108809
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'rectPath') {\n\t\t\t\t\t\t\t\t<pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t\t\t\t\twidth=\"1\"\n\t\t\t\t\t\t\t\t\t\theight=\"1\"\n\t\t\t\t\t\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (placeholderPrompt(); as prompt) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\t[attr.target]=\"run.target ?? '_blank'\"\n\t\t\t[attr.rel]=\"run.rel ?? 'noopener noreferrer'\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!-- `u=\"words\"`: one sibling span per word/gap in place of the piece span. -->\n\t\t\t\t\t@if (piece.words) {\n\t\t\t\t\t\t@for (word of piece.words; track $index) {\n\t\t\t\t\t\t\t<span [ngStyle]=\"word.style\">{{ word.text }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns || run.underlineWordPieces) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns ?? run.underlineWordPieces; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
110264
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t\t[textStyleOverrideCss]=\"textStyleOverrideCss()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides the runs' own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach (the runs declare those unconditionally). -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'rectPath') {\n\t\t\t\t\t\t\t\t<pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t\t\t\t\twidth=\"1\"\n\t\t\t\t\t\t\t\t\t\theight=\"1\"\n\t\t\t\t\t\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (placeholderPrompt(); as prompt) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\t[attr.target]=\"run.target ?? '_blank'\"\n\t\t\t[attr.rel]=\"run.rel ?? 'noopener noreferrer'\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!-- `u=\"words\"`: one sibling span per word/gap in place of the piece span. -->\n\t\t\t\t\t@if (piece.words) {\n\t\t\t\t\t\t@for (word of piece.words; track $index) {\n\t\t\t\t\t\t\t<span [ngStyle]=\"word.style\">{{ word.text }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns || run.underlineWordPieces) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns ?? run.underlineWordPieces; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState", "textStyleOverrideCss"] }, { kind: "component", type: DynamicStyleComponent, selector: "pptx-dynamic-style", inputs: ["css"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
108810
110265
|
}
|
|
108811
110266
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, decorators: [{
|
|
108812
110267
|
type: Component,
|
|
@@ -108814,6 +110269,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
108814
110269
|
NgStyle,
|
|
108815
110270
|
NgTemplateOutlet,
|
|
108816
110271
|
ConnectorRendererComponent,
|
|
110272
|
+
DynamicStyleComponent,
|
|
108817
110273
|
TableRendererComponent,
|
|
108818
110274
|
ChartElementViewComponent,
|
|
108819
110275
|
SmartArtRendererComponent,
|
|
@@ -108826,7 +110282,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
108826
110282
|
ZoomRendererComponent,
|
|
108827
110283
|
EquationRendererComponent,
|
|
108828
110284
|
ImageRendererComponent,
|
|
108829
|
-
], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'rectPath') {\n\t\t\t\t\t\t\t\t<pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t\t\t\t\twidth=\"1\"\n\t\t\t\t\t\t\t\t\t\theight=\"1\"\n\t\t\t\t\t\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (placeholderPrompt(); as prompt) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\t[attr.target]=\"run.target ?? '_blank'\"\n\t\t\t[attr.rel]=\"run.rel ?? 'noopener noreferrer'\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!-- `u=\"words\"`: one sibling span per word/gap in place of the piece span. -->\n\t\t\t\t\t@if (piece.words) {\n\t\t\t\t\t\t@for (word of piece.words; track $index) {\n\t\t\t\t\t\t\t<span [ngStyle]=\"word.style\">{{ word.text }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns || run.underlineWordPieces) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns ?? run.underlineWordPieces; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
|
|
110285
|
+
], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t\t[textStyleOverrideCss]=\"textStyleOverrideCss()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides the runs' own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach (the runs declare those unconditionally). -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'rectPath') {\n\t\t\t\t\t\t\t\t<pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t\t\t\t\twidth=\"1\"\n\t\t\t\t\t\t\t\t\t\theight=\"1\"\n\t\t\t\t\t\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (placeholderPrompt(); as prompt) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\t[attr.target]=\"run.target ?? '_blank'\"\n\t\t\t[attr.rel]=\"run.rel ?? 'noopener noreferrer'\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!-- `u=\"words\"`: one sibling span per word/gap in place of the piece span. -->\n\t\t\t\t\t@if (piece.words) {\n\t\t\t\t\t\t@for (word of piece.words; track $index) {\n\t\t\t\t\t\t\t<span [ngStyle]=\"word.style\">{{ word.text }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns || run.underlineWordPieces) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns ?? run.underlineWordPieces; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
|
|
108830
110286
|
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], obstacles: [{ type: i0.Input, args: [{ isSignal: true, alias: "obstacles", required: false }] }], canvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasWidth", required: false }] }], canvasHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasHeight", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], marked: [{ type: i0.Input, args: [{ isSignal: true, alias: "marked", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], fieldContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldContext", required: false }] }], slideElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideElements", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], parentGroupFill: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentGroupFill", required: false }] }], editingElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingElementId", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }] } });
|
|
108831
110287
|
|
|
108832
110288
|
/**
|
|
@@ -115108,6 +116564,7 @@ class ViewerCollaborationSessionService {
|
|
|
115108
116564
|
canvasHeight: size.height,
|
|
115109
116565
|
getSourceBytes: () => host.getSourceBytes(),
|
|
115110
116566
|
getTemplateElements: () => host.getTemplateElements(),
|
|
116567
|
+
getSaveOptions: () => host.getSaveOptions(),
|
|
115111
116568
|
};
|
|
115112
116569
|
}
|
|
115113
116570
|
/**
|
|
@@ -128581,7 +130038,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
128581
130038
|
}], 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 }] }] } });
|
|
128582
130039
|
|
|
128583
130040
|
// Generated by scripts/inline-shared.mjs from package.json. Do not edit.
|
|
128584
|
-
const PPTX_ANGULAR_VIEWER_VERSION = "3.
|
|
130041
|
+
const PPTX_ANGULAR_VIEWER_VERSION = "3.8.0";
|
|
128585
130042
|
|
|
128586
130043
|
/**
|
|
128587
130044
|
* account-page.component.ts: File > Account content.
|
|
@@ -134416,6 +135873,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
134416
135873
|
`, styles: [".hdr{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border-bottom:1px solid var(--pptx-inspector-border, rgba(0, 0, 0, .1))}.hdr__tabs{display:flex;align-items:center;gap:2px;border-radius:4px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));padding:2px}.hdr__tab{display:flex;align-items:center;gap:4px;padding:3px 8px;border:none;border-radius:3px;background:transparent;color:var(--pptx-inspector-muted, #888);font-size:11px;font-family:inherit;cursor:pointer}.hdr__tab.is-active{background:var(--pptx-inspector-active, #0078d4);color:#fff}.hdr__icon{width:14px;height:14px;flex-shrink:0}.hdr__icon--close{width:16px;height:16px}.hdr__close{display:flex;align-items:center;justify-content:center;padding:4px;border:none;border-radius:3px;background:transparent;color:var(--pptx-inspector-muted, #888);cursor:pointer}.hdr__close:hover,.hdr__tab:not(.is-active):hover{color:inherit}\n"] }]
|
|
134417
135874
|
}], propDecorators: { activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }], closePane: [{ type: i0.Output, args: ["closePane"] }] } });
|
|
134418
135875
|
|
|
135876
|
+
/**
|
|
135877
|
+
* Alt text / title editor for a plain shape, text box or connector, at
|
|
135878
|
+
* parity with React's `AccessibilityTextSection` and Vue's
|
|
135879
|
+
* `AccessibilityPanel.vue`.
|
|
135880
|
+
*
|
|
135881
|
+
* A picture's own alt text field lives in `ImagePropertiesPanelComponent`;
|
|
135882
|
+
* this covers the three element kinds that only started modelling `altText`
|
|
135883
|
+
* / `title` once core parsed `p:cNvPr/@descr` / `@title` on `p:sp` / `p:cxnSp`
|
|
135884
|
+
* (see `PptxNonVisualDescription`). `getNonVisualDescriptionFields` (shared)
|
|
135885
|
+
* decides which fields apply so this component stays a thin view.
|
|
135886
|
+
*/
|
|
135887
|
+
class AccessibilityTextPanelComponent {
|
|
135888
|
+
constructor() {
|
|
135889
|
+
this.element = input.required(/* @ts-ignore */
|
|
135890
|
+
...(ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []));
|
|
135891
|
+
this.patch = output();
|
|
135892
|
+
this.fields = computed(() => getNonVisualDescriptionFields(this.element()), /* @ts-ignore */
|
|
135893
|
+
...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
135894
|
+
}
|
|
135895
|
+
/** Whether the selected element kind supports either field. */
|
|
135896
|
+
static supports(element) {
|
|
135897
|
+
return element.type === 'text' || element.type === 'shape' || element.type === 'connector';
|
|
135898
|
+
}
|
|
135899
|
+
onAltText(event) {
|
|
135900
|
+
this.patch.emit({
|
|
135901
|
+
altText: event.target.value,
|
|
135902
|
+
});
|
|
135903
|
+
}
|
|
135904
|
+
onTitle(event) {
|
|
135905
|
+
this.patch.emit({ title: event.target.value });
|
|
135906
|
+
}
|
|
135907
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: AccessibilityTextPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
135908
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: AccessibilityTextPanelComponent, isStandalone: true, selector: "pptx-accessibility-text-panel", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patch: "patch" }, ngImport: i0, template: `
|
|
135909
|
+
@if (fields().showAltText || fields().showTitle) {
|
|
135910
|
+
<div class="pptx-ng-accessibility-text" data-pptx-accessibility-text>
|
|
135911
|
+
@if (fields().showAltText) {
|
|
135912
|
+
<label class="field field--stacked">
|
|
135913
|
+
<span>{{ 'pptx.elementAccessibility.altText' | translate }}</span>
|
|
135914
|
+
<textarea
|
|
135915
|
+
rows="2"
|
|
135916
|
+
[value]="fields().altText"
|
|
135917
|
+
[placeholder]="'pptx.elementAccessibility.altTextPlaceholder' | translate"
|
|
135918
|
+
(input)="onAltText($event)"
|
|
135919
|
+
></textarea>
|
|
135920
|
+
</label>
|
|
135921
|
+
}
|
|
135922
|
+
@if (fields().showTitle) {
|
|
135923
|
+
<label class="field field--stacked">
|
|
135924
|
+
<span>{{ 'pptx.elementAccessibility.title' | translate }}</span>
|
|
135925
|
+
<input
|
|
135926
|
+
type="text"
|
|
135927
|
+
[value]="fields().title"
|
|
135928
|
+
[placeholder]="'pptx.elementAccessibility.titlePlaceholder' | translate"
|
|
135929
|
+
(input)="onTitle($event)"
|
|
135930
|
+
/>
|
|
135931
|
+
</label>
|
|
135932
|
+
}
|
|
135933
|
+
</div>
|
|
135934
|
+
}
|
|
135935
|
+
`, isInline: true, styles: [".pptx-ng-accessibility-text{display:grid;gap:9px;font-size:11px}.field{display:grid;gap:4px;color:var(--pptx-inspector-muted, #aaa)}.field--stacked{grid-template-columns:1fr}input[type=text],textarea{box-sizing:border-box;width:100%;padding:4px 6px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit;font:inherit;resize:vertical}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
135936
|
+
}
|
|
135937
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: AccessibilityTextPanelComponent, decorators: [{
|
|
135938
|
+
type: Component,
|
|
135939
|
+
args: [{ selector: 'pptx-accessibility-text-panel', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
135940
|
+
@if (fields().showAltText || fields().showTitle) {
|
|
135941
|
+
<div class="pptx-ng-accessibility-text" data-pptx-accessibility-text>
|
|
135942
|
+
@if (fields().showAltText) {
|
|
135943
|
+
<label class="field field--stacked">
|
|
135944
|
+
<span>{{ 'pptx.elementAccessibility.altText' | translate }}</span>
|
|
135945
|
+
<textarea
|
|
135946
|
+
rows="2"
|
|
135947
|
+
[value]="fields().altText"
|
|
135948
|
+
[placeholder]="'pptx.elementAccessibility.altTextPlaceholder' | translate"
|
|
135949
|
+
(input)="onAltText($event)"
|
|
135950
|
+
></textarea>
|
|
135951
|
+
</label>
|
|
135952
|
+
}
|
|
135953
|
+
@if (fields().showTitle) {
|
|
135954
|
+
<label class="field field--stacked">
|
|
135955
|
+
<span>{{ 'pptx.elementAccessibility.title' | translate }}</span>
|
|
135956
|
+
<input
|
|
135957
|
+
type="text"
|
|
135958
|
+
[value]="fields().title"
|
|
135959
|
+
[placeholder]="'pptx.elementAccessibility.titlePlaceholder' | translate"
|
|
135960
|
+
(input)="onTitle($event)"
|
|
135961
|
+
/>
|
|
135962
|
+
</label>
|
|
135963
|
+
}
|
|
135964
|
+
</div>
|
|
135965
|
+
}
|
|
135966
|
+
`, styles: [".pptx-ng-accessibility-text{display:grid;gap:9px;font-size:11px}.field{display:grid;gap:4px;color:var(--pptx-inspector-muted, #aaa)}.field--stacked{grid-template-columns:1fr}input[type=text],textarea{box-sizing:border-box;width:100%;padding:4px 6px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit;font:inherit;resize:vertical}\n"] }]
|
|
135967
|
+
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], patch: [{ type: i0.Output, args: ["patch"] }] } });
|
|
135968
|
+
|
|
134419
135969
|
/**
|
|
134420
135970
|
* action-target-fields.component.ts: the target input for one Action Settings
|
|
134421
135971
|
* trigger, split out of `ActionSettingsPanelComponent` to keep that file under
|
|
@@ -139602,7 +141152,10 @@ class ChartTypeSelectorComponent {
|
|
|
139602
141152
|
onTitle(event) {
|
|
139603
141153
|
const target = event.target;
|
|
139604
141154
|
if (target instanceof HTMLInputElement) {
|
|
139605
|
-
|
|
141155
|
+
// A multi-run title collapses to one run in its dominant style so an
|
|
141156
|
+
// edit does not leave another, now-stale run's text trailing the new
|
|
141157
|
+
// title; see `collapseChartTitleRunsForEdit`'s doc.
|
|
141158
|
+
this.emit(collapseChartTitleRunsForEdit(this.data(), target.value));
|
|
139606
141159
|
}
|
|
139607
141160
|
}
|
|
139608
141161
|
onType(event) {
|
|
@@ -143533,7 +145086,7 @@ class SmartArtPropertiesComponent {
|
|
|
143533
145086
|
this.commit(moveNodeDown(this.smartArtData(), nodeId));
|
|
143534
145087
|
}
|
|
143535
145088
|
onNodeFillColor(event, nodeId) {
|
|
143536
|
-
const value = inputValue$
|
|
145089
|
+
const value = inputValue$3(event);
|
|
143537
145090
|
if (value === null) {
|
|
143538
145091
|
return;
|
|
143539
145092
|
}
|
|
@@ -143541,7 +145094,7 @@ class SmartArtPropertiesComponent {
|
|
|
143541
145094
|
this.recentColors?.push(value);
|
|
143542
145095
|
}
|
|
143543
145096
|
onNodeFontColor(event, nodeId) {
|
|
143544
|
-
const value = inputValue$
|
|
145097
|
+
const value = inputValue$3(event);
|
|
143545
145098
|
if (value === null) {
|
|
143546
145099
|
return;
|
|
143547
145100
|
}
|
|
@@ -143555,7 +145108,7 @@ class SmartArtPropertiesComponent {
|
|
|
143555
145108
|
this.commit(toggleNodeItalic(this.smartArtData(), node));
|
|
143556
145109
|
}
|
|
143557
145110
|
onNodeText(event, nodeId) {
|
|
143558
|
-
const value = inputValue$
|
|
145111
|
+
const value = inputValue$3(event);
|
|
143559
145112
|
if (value === null) {
|
|
143560
145113
|
return;
|
|
143561
145114
|
}
|
|
@@ -144050,7 +145603,7 @@ function selectValue$1(event) {
|
|
|
144050
145603
|
return target instanceof HTMLSelectElement ? target.value : null;
|
|
144051
145604
|
}
|
|
144052
145605
|
/** Read the value of an `<input>` change event. */
|
|
144053
|
-
function inputValue$
|
|
145606
|
+
function inputValue$3(event) {
|
|
144054
145607
|
const target = event.target;
|
|
144055
145608
|
return target instanceof HTMLInputElement ? target.value : null;
|
|
144056
145609
|
}
|
|
@@ -144225,7 +145778,7 @@ class TableCellAdvancedFillComponent {
|
|
|
144225
145778
|
this.emitGradient(this.stops(), this.gradType(), angle);
|
|
144226
145779
|
}
|
|
144227
145780
|
onStopColor(index, event) {
|
|
144228
|
-
const color = inputValue$
|
|
145781
|
+
const color = inputValue$2(event);
|
|
144229
145782
|
this.updateStop(index, { color });
|
|
144230
145783
|
}
|
|
144231
145784
|
onStopPos(index, event) {
|
|
@@ -144240,10 +145793,10 @@ class TableCellAdvancedFillComponent {
|
|
|
144240
145793
|
this.styleChange.emit({ patternFillPreset: selectValue(event) });
|
|
144241
145794
|
}
|
|
144242
145795
|
onPatternFg(event) {
|
|
144243
|
-
this.styleChange.emit({ patternFillForeground: inputValue$
|
|
145796
|
+
this.styleChange.emit({ patternFillForeground: inputValue$2(event) });
|
|
144244
145797
|
}
|
|
144245
145798
|
onPatternBg(event) {
|
|
144246
|
-
this.styleChange.emit({ patternFillBackground: inputValue$
|
|
145799
|
+
this.styleChange.emit({ patternFillBackground: inputValue$2(event) });
|
|
144247
145800
|
}
|
|
144248
145801
|
onMargin(key, event) {
|
|
144249
145802
|
const value = numberValue(event);
|
|
@@ -144256,7 +145809,7 @@ class TableCellAdvancedFillComponent {
|
|
|
144256
145809
|
* colour into the shared "Recent colours" list.
|
|
144257
145810
|
*/
|
|
144258
145811
|
pushRecentColor(event) {
|
|
144259
|
-
const value = inputValue$
|
|
145812
|
+
const value = inputValue$2(event);
|
|
144260
145813
|
if (value) {
|
|
144261
145814
|
this.recentColors?.push(value);
|
|
144262
145815
|
}
|
|
@@ -144579,7 +146132,7 @@ function selectValue(event) {
|
|
|
144579
146132
|
const t = event.target;
|
|
144580
146133
|
return t instanceof HTMLSelectElement ? t.value : '';
|
|
144581
146134
|
}
|
|
144582
|
-
function inputValue$
|
|
146135
|
+
function inputValue$2(event) {
|
|
144583
146136
|
const t = event.target;
|
|
144584
146137
|
return t instanceof HTMLInputElement ? t.value : '';
|
|
144585
146138
|
}
|
|
@@ -144629,14 +146182,14 @@ class TableCellColorFieldComponent {
|
|
|
144629
146182
|
}
|
|
144630
146183
|
/** Live preview while dragging the native picker: no theme identity, so always clears the ref. */
|
|
144631
146184
|
onNativeChange(event) {
|
|
144632
|
-
const value = inputValue(event);
|
|
146185
|
+
const value = inputValue$1(event);
|
|
144633
146186
|
if (value) {
|
|
144634
146187
|
this.commit.emit({ hex: value, ref: undefined });
|
|
144635
146188
|
}
|
|
144636
146189
|
}
|
|
144637
146190
|
/** The committed (native `change`, not the live-preview `input`) colour: record it as recent. */
|
|
144638
146191
|
onNativeCommit(event) {
|
|
144639
|
-
const value = inputValue(event);
|
|
146192
|
+
const value = inputValue$1(event);
|
|
144640
146193
|
if (value) {
|
|
144641
146194
|
this.recentColors?.push(value);
|
|
144642
146195
|
}
|
|
@@ -144689,7 +146242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
144689
146242
|
</label>
|
|
144690
146243
|
`, styles: [".pptx-tccf__field{display:flex;flex-direction:column;gap:.2rem}.pptx-tccf__lbl{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tccf__color{width:28px;height:22px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}\n"] }]
|
|
144691
146244
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: true }] }], selectedRef: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedRef", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], commit: [{ type: i0.Output, args: ["commit"] }] } });
|
|
144692
|
-
function inputValue(event) {
|
|
146245
|
+
function inputValue$1(event) {
|
|
144693
146246
|
const t = event.target;
|
|
144694
146247
|
return t instanceof HTMLInputElement ? t.value : '';
|
|
144695
146248
|
}
|
|
@@ -145655,6 +147208,616 @@ function stringFromEvent$1(event) {
|
|
|
145655
147208
|
return target.value;
|
|
145656
147209
|
}
|
|
145657
147210
|
|
|
147211
|
+
/**
|
|
147212
|
+
* table-style-editor-fields.component.ts: field editors (fill/text/borders)
|
|
147213
|
+
* for whichever part `TableStyleEditorComponent` currently has selected.
|
|
147214
|
+
* Split out from that shell purely to keep both files under the repo's
|
|
147215
|
+
* 300-LOC budget. Mirrors React's `TableStyleEditorFields.tsx` and Vue's
|
|
147216
|
+
* `TableStyleEditorFields.vue`.
|
|
147217
|
+
*
|
|
147218
|
+
* @module viewer/table-style-editor-fields
|
|
147219
|
+
*/
|
|
147220
|
+
function inputValue(event) {
|
|
147221
|
+
const t = event.target;
|
|
147222
|
+
return t instanceof HTMLInputElement || t instanceof HTMLSelectElement ? t.value : '';
|
|
147223
|
+
}
|
|
147224
|
+
function checkedValue(event) {
|
|
147225
|
+
const t = event.target;
|
|
147226
|
+
return t instanceof HTMLInputElement ? t.checked : false;
|
|
147227
|
+
}
|
|
147228
|
+
class TableStyleEditorFieldsComponent {
|
|
147229
|
+
constructor() {
|
|
147230
|
+
this.descriptor = input.required(/* @ts-ignore */
|
|
147231
|
+
...(ngDevMode ? [{ debugName: "descriptor" }] : /* istanbul ignore next */ []));
|
|
147232
|
+
this.canEdit = input(true, /* @ts-ignore */
|
|
147233
|
+
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
147234
|
+
this.edit = output();
|
|
147235
|
+
this.sides = TABLE_STYLE_BORDER_SIDES;
|
|
147236
|
+
this.dashPresets = TABLE_STYLE_DASH_PRESETS;
|
|
147237
|
+
this.borderSideLabelKeys = TABLE_STYLE_BORDER_SIDE_LABEL_KEYS;
|
|
147238
|
+
}
|
|
147239
|
+
inputValue(event) {
|
|
147240
|
+
return inputValue(event);
|
|
147241
|
+
}
|
|
147242
|
+
/** Templates cannot reach the `Number` global, so the coercion lives here. */
|
|
147243
|
+
inputNumber(event) {
|
|
147244
|
+
return Number(inputValue(event));
|
|
147245
|
+
}
|
|
147246
|
+
checkedValue(event) {
|
|
147247
|
+
return checkedValue(event);
|
|
147248
|
+
}
|
|
147249
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorFieldsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
147250
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TableStyleEditorFieldsComponent, isStandalone: true, selector: "pptx-table-style-editor-fields", inputs: { descriptor: { classPropertyName: "descriptor", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "edit" }, ngImport: i0, template: `
|
|
147251
|
+
@if (descriptor(); as d) {
|
|
147252
|
+
<div class="pptx-tse-fields">
|
|
147253
|
+
<div class="pptx-tse-fields__group">
|
|
147254
|
+
<div class="pptx-tse-fields__hdg">
|
|
147255
|
+
{{ 'pptx.tableStyleEditor.fillSection' | translate }}
|
|
147256
|
+
</div>
|
|
147257
|
+
<div class="pptx-tse-fields__row">
|
|
147258
|
+
<input
|
|
147259
|
+
type="color"
|
|
147260
|
+
class="pptx-tse-fields__color"
|
|
147261
|
+
[disabled]="!canEdit()"
|
|
147262
|
+
[value]="d.fill.color.hex"
|
|
147263
|
+
(change)="edit.emit({ kind: 'fillColor', hex: inputValue($event), ref: undefined })"
|
|
147264
|
+
/>
|
|
147265
|
+
<label class="pptx-tse-fields__check">
|
|
147266
|
+
<input
|
|
147267
|
+
type="checkbox"
|
|
147268
|
+
[disabled]="!canEdit()"
|
|
147269
|
+
[checked]="d.fill.noFill"
|
|
147270
|
+
(change)="edit.emit({ kind: 'fillNone', noFill: checkedValue($event) })"
|
|
147271
|
+
/>
|
|
147272
|
+
{{ 'pptx.tableStyleEditor.noFill' | translate }}
|
|
147273
|
+
</label>
|
|
147274
|
+
</div>
|
|
147275
|
+
<pptx-theme-color-swatch-grid
|
|
147276
|
+
[disabled]="!canEdit()"
|
|
147277
|
+
[selectedRef]="d.fill.color.ref"
|
|
147278
|
+
[selectedHex]="d.fill.color.hex"
|
|
147279
|
+
(pick)="edit.emit({ kind: 'fillColor', hex: $event.hex, ref: $event.ref })"
|
|
147280
|
+
/>
|
|
147281
|
+
</div>
|
|
147282
|
+
|
|
147283
|
+
@if (d.hasTextAndBorders) {
|
|
147284
|
+
<div class="pptx-tse-fields__group">
|
|
147285
|
+
<div class="pptx-tse-fields__hdg">
|
|
147286
|
+
{{ 'pptx.tableStyleEditor.textSection' | translate }}
|
|
147287
|
+
</div>
|
|
147288
|
+
<div class="pptx-tse-fields__row">
|
|
147289
|
+
<button
|
|
147290
|
+
type="button"
|
|
147291
|
+
[disabled]="!canEdit()"
|
|
147292
|
+
[class.pptx-tse-fields__active]="d.text.bold"
|
|
147293
|
+
(click)="edit.emit({ kind: 'textBold', value: !d.text.bold })"
|
|
147294
|
+
>
|
|
147295
|
+
{{ 'pptx.format.bold' | translate }}
|
|
147296
|
+
</button>
|
|
147297
|
+
<button
|
|
147298
|
+
type="button"
|
|
147299
|
+
[disabled]="!canEdit()"
|
|
147300
|
+
[class.pptx-tse-fields__active]="d.text.italic"
|
|
147301
|
+
(click)="edit.emit({ kind: 'textItalic', value: !d.text.italic })"
|
|
147302
|
+
>
|
|
147303
|
+
{{ 'pptx.format.italic' | translate }}
|
|
147304
|
+
</button>
|
|
147305
|
+
<button
|
|
147306
|
+
type="button"
|
|
147307
|
+
[disabled]="!canEdit()"
|
|
147308
|
+
[class.pptx-tse-fields__active]="d.text.underline"
|
|
147309
|
+
(click)="edit.emit({ kind: 'textUnderline', value: !d.text.underline })"
|
|
147310
|
+
>
|
|
147311
|
+
{{ 'pptx.format.underline' | translate }}
|
|
147312
|
+
</button>
|
|
147313
|
+
</div>
|
|
147314
|
+
<label class="pptx-tse-fields__row">
|
|
147315
|
+
<span>{{ 'pptx.tableStyleEditor.textColor' | translate }}</span>
|
|
147316
|
+
<input
|
|
147317
|
+
type="color"
|
|
147318
|
+
class="pptx-tse-fields__color"
|
|
147319
|
+
[disabled]="!canEdit()"
|
|
147320
|
+
[value]="d.text.color.hex"
|
|
147321
|
+
(change)="edit.emit({ kind: 'textColor', hex: inputValue($event), ref: undefined })"
|
|
147322
|
+
/>
|
|
147323
|
+
</label>
|
|
147324
|
+
<pptx-theme-color-swatch-grid
|
|
147325
|
+
[disabled]="!canEdit()"
|
|
147326
|
+
[selectedRef]="d.text.color.ref"
|
|
147327
|
+
[selectedHex]="d.text.color.hex"
|
|
147328
|
+
(pick)="edit.emit({ kind: 'textColor', hex: $event.hex, ref: $event.ref })"
|
|
147329
|
+
/>
|
|
147330
|
+
</div>
|
|
147331
|
+
|
|
147332
|
+
<div class="pptx-tse-fields__group">
|
|
147333
|
+
<div class="pptx-tse-fields__hdg">
|
|
147334
|
+
{{ 'pptx.tableStyleEditor.bordersSection' | translate }}
|
|
147335
|
+
</div>
|
|
147336
|
+
@for (side of sides; track side) {
|
|
147337
|
+
<div class="pptx-tse-fields__border-row">
|
|
147338
|
+
<span class="pptx-tse-fields__side-lbl">{{
|
|
147339
|
+
borderSideLabelKeys[side] | translate
|
|
147340
|
+
}}</span>
|
|
147341
|
+
<input
|
|
147342
|
+
type="color"
|
|
147343
|
+
class="pptx-tse-fields__color pptx-tse-fields__color--sm"
|
|
147344
|
+
[disabled]="!canEdit()"
|
|
147345
|
+
[value]="d.borders[side].color.hex"
|
|
147346
|
+
(change)="
|
|
147347
|
+
edit.emit({
|
|
147348
|
+
kind: 'borderColor',
|
|
147349
|
+
side,
|
|
147350
|
+
hex: inputValue($event),
|
|
147351
|
+
ref: undefined,
|
|
147352
|
+
})
|
|
147353
|
+
"
|
|
147354
|
+
/>
|
|
147355
|
+
<input
|
|
147356
|
+
type="number"
|
|
147357
|
+
min="0"
|
|
147358
|
+
max="20"
|
|
147359
|
+
class="pptx-tse-fields__num"
|
|
147360
|
+
[disabled]="!canEdit()"
|
|
147361
|
+
[value]="d.borders[side].width"
|
|
147362
|
+
(change)="edit.emit({ kind: 'borderWidth', side, width: inputNumber($event) })"
|
|
147363
|
+
/>
|
|
147364
|
+
<select
|
|
147365
|
+
class="pptx-tse-fields__dash"
|
|
147366
|
+
[disabled]="!canEdit()"
|
|
147367
|
+
[value]="d.borders[side].dash"
|
|
147368
|
+
(change)="edit.emit({ kind: 'borderDash', side, dash: inputValue($event) })"
|
|
147369
|
+
>
|
|
147370
|
+
@for (dash of dashPresets; track dash) {
|
|
147371
|
+
<option [value]="dash" [selected]="dash === d.borders[side].dash">
|
|
147372
|
+
{{ dash }}
|
|
147373
|
+
</option>
|
|
147374
|
+
}
|
|
147375
|
+
</select>
|
|
147376
|
+
<label class="pptx-tse-fields__check">
|
|
147377
|
+
<input
|
|
147378
|
+
type="checkbox"
|
|
147379
|
+
[disabled]="!canEdit()"
|
|
147380
|
+
[checked]="d.borders[side].noFill"
|
|
147381
|
+
(change)="edit.emit({ kind: 'borderNone', side, noFill: checkedValue($event) })"
|
|
147382
|
+
/>
|
|
147383
|
+
{{ 'pptx.tableStyleEditor.noBorder' | translate }}
|
|
147384
|
+
</label>
|
|
147385
|
+
</div>
|
|
147386
|
+
}
|
|
147387
|
+
</div>
|
|
147388
|
+
}
|
|
147389
|
+
</div>
|
|
147390
|
+
}
|
|
147391
|
+
`, isInline: true, styles: [".pptx-tse-fields{display:flex;flex-direction:column;gap:.5rem}.pptx-tse-fields__group{display:flex;flex-direction:column;gap:.25rem}.pptx-tse-fields__hdg{font-size:10px;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-inspector-muted, #888)}.pptx-tse-fields__row{display:flex;align-items:center;gap:.5rem;font-size:11px}.pptx-tse-fields__check{display:flex;align-items:center;gap:.25rem;font-size:11px}.pptx-tse-fields__color{height:1.5rem;width:2rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.pptx-tse-fields__color--sm{width:1.75rem}.pptx-tse-fields__border-row{display:flex;align-items:center;gap:.4rem;font-size:11px}.pptx-tse-fields__side-lbl{width:7rem;flex-shrink:0;color:var(--pptx-inspector-muted, #888)}.pptx-tse-fields__num{width:3rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit}.pptx-tse-fields__dash{border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit}.pptx-tse-fields__active{background:var(--pptx-inspector-active, #3a3a3a)}\n"], dependencies: [{ kind: "component", type: ThemeColorSwatchGridComponent, selector: "pptx-theme-color-swatch-grid", inputs: ["disabled", "selectedRef", "selectedHex"], outputs: ["pick"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
147392
|
+
}
|
|
147393
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorFieldsComponent, decorators: [{
|
|
147394
|
+
type: Component,
|
|
147395
|
+
args: [{ selector: 'pptx-table-style-editor-fields', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe, ThemeColorSwatchGridComponent], template: `
|
|
147396
|
+
@if (descriptor(); as d) {
|
|
147397
|
+
<div class="pptx-tse-fields">
|
|
147398
|
+
<div class="pptx-tse-fields__group">
|
|
147399
|
+
<div class="pptx-tse-fields__hdg">
|
|
147400
|
+
{{ 'pptx.tableStyleEditor.fillSection' | translate }}
|
|
147401
|
+
</div>
|
|
147402
|
+
<div class="pptx-tse-fields__row">
|
|
147403
|
+
<input
|
|
147404
|
+
type="color"
|
|
147405
|
+
class="pptx-tse-fields__color"
|
|
147406
|
+
[disabled]="!canEdit()"
|
|
147407
|
+
[value]="d.fill.color.hex"
|
|
147408
|
+
(change)="edit.emit({ kind: 'fillColor', hex: inputValue($event), ref: undefined })"
|
|
147409
|
+
/>
|
|
147410
|
+
<label class="pptx-tse-fields__check">
|
|
147411
|
+
<input
|
|
147412
|
+
type="checkbox"
|
|
147413
|
+
[disabled]="!canEdit()"
|
|
147414
|
+
[checked]="d.fill.noFill"
|
|
147415
|
+
(change)="edit.emit({ kind: 'fillNone', noFill: checkedValue($event) })"
|
|
147416
|
+
/>
|
|
147417
|
+
{{ 'pptx.tableStyleEditor.noFill' | translate }}
|
|
147418
|
+
</label>
|
|
147419
|
+
</div>
|
|
147420
|
+
<pptx-theme-color-swatch-grid
|
|
147421
|
+
[disabled]="!canEdit()"
|
|
147422
|
+
[selectedRef]="d.fill.color.ref"
|
|
147423
|
+
[selectedHex]="d.fill.color.hex"
|
|
147424
|
+
(pick)="edit.emit({ kind: 'fillColor', hex: $event.hex, ref: $event.ref })"
|
|
147425
|
+
/>
|
|
147426
|
+
</div>
|
|
147427
|
+
|
|
147428
|
+
@if (d.hasTextAndBorders) {
|
|
147429
|
+
<div class="pptx-tse-fields__group">
|
|
147430
|
+
<div class="pptx-tse-fields__hdg">
|
|
147431
|
+
{{ 'pptx.tableStyleEditor.textSection' | translate }}
|
|
147432
|
+
</div>
|
|
147433
|
+
<div class="pptx-tse-fields__row">
|
|
147434
|
+
<button
|
|
147435
|
+
type="button"
|
|
147436
|
+
[disabled]="!canEdit()"
|
|
147437
|
+
[class.pptx-tse-fields__active]="d.text.bold"
|
|
147438
|
+
(click)="edit.emit({ kind: 'textBold', value: !d.text.bold })"
|
|
147439
|
+
>
|
|
147440
|
+
{{ 'pptx.format.bold' | translate }}
|
|
147441
|
+
</button>
|
|
147442
|
+
<button
|
|
147443
|
+
type="button"
|
|
147444
|
+
[disabled]="!canEdit()"
|
|
147445
|
+
[class.pptx-tse-fields__active]="d.text.italic"
|
|
147446
|
+
(click)="edit.emit({ kind: 'textItalic', value: !d.text.italic })"
|
|
147447
|
+
>
|
|
147448
|
+
{{ 'pptx.format.italic' | translate }}
|
|
147449
|
+
</button>
|
|
147450
|
+
<button
|
|
147451
|
+
type="button"
|
|
147452
|
+
[disabled]="!canEdit()"
|
|
147453
|
+
[class.pptx-tse-fields__active]="d.text.underline"
|
|
147454
|
+
(click)="edit.emit({ kind: 'textUnderline', value: !d.text.underline })"
|
|
147455
|
+
>
|
|
147456
|
+
{{ 'pptx.format.underline' | translate }}
|
|
147457
|
+
</button>
|
|
147458
|
+
</div>
|
|
147459
|
+
<label class="pptx-tse-fields__row">
|
|
147460
|
+
<span>{{ 'pptx.tableStyleEditor.textColor' | translate }}</span>
|
|
147461
|
+
<input
|
|
147462
|
+
type="color"
|
|
147463
|
+
class="pptx-tse-fields__color"
|
|
147464
|
+
[disabled]="!canEdit()"
|
|
147465
|
+
[value]="d.text.color.hex"
|
|
147466
|
+
(change)="edit.emit({ kind: 'textColor', hex: inputValue($event), ref: undefined })"
|
|
147467
|
+
/>
|
|
147468
|
+
</label>
|
|
147469
|
+
<pptx-theme-color-swatch-grid
|
|
147470
|
+
[disabled]="!canEdit()"
|
|
147471
|
+
[selectedRef]="d.text.color.ref"
|
|
147472
|
+
[selectedHex]="d.text.color.hex"
|
|
147473
|
+
(pick)="edit.emit({ kind: 'textColor', hex: $event.hex, ref: $event.ref })"
|
|
147474
|
+
/>
|
|
147475
|
+
</div>
|
|
147476
|
+
|
|
147477
|
+
<div class="pptx-tse-fields__group">
|
|
147478
|
+
<div class="pptx-tse-fields__hdg">
|
|
147479
|
+
{{ 'pptx.tableStyleEditor.bordersSection' | translate }}
|
|
147480
|
+
</div>
|
|
147481
|
+
@for (side of sides; track side) {
|
|
147482
|
+
<div class="pptx-tse-fields__border-row">
|
|
147483
|
+
<span class="pptx-tse-fields__side-lbl">{{
|
|
147484
|
+
borderSideLabelKeys[side] | translate
|
|
147485
|
+
}}</span>
|
|
147486
|
+
<input
|
|
147487
|
+
type="color"
|
|
147488
|
+
class="pptx-tse-fields__color pptx-tse-fields__color--sm"
|
|
147489
|
+
[disabled]="!canEdit()"
|
|
147490
|
+
[value]="d.borders[side].color.hex"
|
|
147491
|
+
(change)="
|
|
147492
|
+
edit.emit({
|
|
147493
|
+
kind: 'borderColor',
|
|
147494
|
+
side,
|
|
147495
|
+
hex: inputValue($event),
|
|
147496
|
+
ref: undefined,
|
|
147497
|
+
})
|
|
147498
|
+
"
|
|
147499
|
+
/>
|
|
147500
|
+
<input
|
|
147501
|
+
type="number"
|
|
147502
|
+
min="0"
|
|
147503
|
+
max="20"
|
|
147504
|
+
class="pptx-tse-fields__num"
|
|
147505
|
+
[disabled]="!canEdit()"
|
|
147506
|
+
[value]="d.borders[side].width"
|
|
147507
|
+
(change)="edit.emit({ kind: 'borderWidth', side, width: inputNumber($event) })"
|
|
147508
|
+
/>
|
|
147509
|
+
<select
|
|
147510
|
+
class="pptx-tse-fields__dash"
|
|
147511
|
+
[disabled]="!canEdit()"
|
|
147512
|
+
[value]="d.borders[side].dash"
|
|
147513
|
+
(change)="edit.emit({ kind: 'borderDash', side, dash: inputValue($event) })"
|
|
147514
|
+
>
|
|
147515
|
+
@for (dash of dashPresets; track dash) {
|
|
147516
|
+
<option [value]="dash" [selected]="dash === d.borders[side].dash">
|
|
147517
|
+
{{ dash }}
|
|
147518
|
+
</option>
|
|
147519
|
+
}
|
|
147520
|
+
</select>
|
|
147521
|
+
<label class="pptx-tse-fields__check">
|
|
147522
|
+
<input
|
|
147523
|
+
type="checkbox"
|
|
147524
|
+
[disabled]="!canEdit()"
|
|
147525
|
+
[checked]="d.borders[side].noFill"
|
|
147526
|
+
(change)="edit.emit({ kind: 'borderNone', side, noFill: checkedValue($event) })"
|
|
147527
|
+
/>
|
|
147528
|
+
{{ 'pptx.tableStyleEditor.noBorder' | translate }}
|
|
147529
|
+
</label>
|
|
147530
|
+
</div>
|
|
147531
|
+
}
|
|
147532
|
+
</div>
|
|
147533
|
+
}
|
|
147534
|
+
</div>
|
|
147535
|
+
}
|
|
147536
|
+
`, styles: [".pptx-tse-fields{display:flex;flex-direction:column;gap:.5rem}.pptx-tse-fields__group{display:flex;flex-direction:column;gap:.25rem}.pptx-tse-fields__hdg{font-size:10px;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-inspector-muted, #888)}.pptx-tse-fields__row{display:flex;align-items:center;gap:.5rem;font-size:11px}.pptx-tse-fields__check{display:flex;align-items:center;gap:.25rem;font-size:11px}.pptx-tse-fields__color{height:1.5rem;width:2rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.pptx-tse-fields__color--sm{width:1.75rem}.pptx-tse-fields__border-row{display:flex;align-items:center;gap:.4rem;font-size:11px}.pptx-tse-fields__side-lbl{width:7rem;flex-shrink:0;color:var(--pptx-inspector-muted, #888)}.pptx-tse-fields__num{width:3rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit}.pptx-tse-fields__dash{border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, #2d2d2d);color:inherit}.pptx-tse-fields__active{background:var(--pptx-inspector-active, #3a3a3a)}\n"] }]
|
|
147537
|
+
}], propDecorators: { descriptor: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptor", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], edit: [{ type: i0.Output, args: ["edit"] }] } });
|
|
147538
|
+
|
|
147539
|
+
/**
|
|
147540
|
+
* table-style-editor.component.ts: "Edit style..." panel for a table style's
|
|
147541
|
+
* own DEFINITION (`a:tblStyleLst` section fill/text/borders/cell3D), distinct
|
|
147542
|
+
* from `TablePropertiesComponent`'s "which style does this table use" picker.
|
|
147543
|
+
* Angular port of React's `TableStyleEditor.tsx` / Vue's `TableStyleEditor.vue`.
|
|
147544
|
+
*
|
|
147545
|
+
* @module viewer/table-style-editor
|
|
147546
|
+
*/
|
|
147547
|
+
class TableStyleEditorComponent {
|
|
147548
|
+
constructor() {
|
|
147549
|
+
this.styleMap = input(undefined, /* @ts-ignore */
|
|
147550
|
+
...(ngDevMode ? [{ debugName: "styleMap" }] : /* istanbul ignore next */ []));
|
|
147551
|
+
/** The style currently assigned to the table being edited. */
|
|
147552
|
+
this.styleId = input(undefined, /* @ts-ignore */
|
|
147553
|
+
...(ngDevMode ? [{ debugName: "styleId" }] : /* istanbul ignore next */ []));
|
|
147554
|
+
this.canEdit = input(true, /* @ts-ignore */
|
|
147555
|
+
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
147556
|
+
/** Commit a full replacement style map (section edit, create, or delete already applied). */
|
|
147557
|
+
this.styleMapChange = output();
|
|
147558
|
+
/** Record a styleId for save-time removal from `ppt/tableStyles.xml`. */
|
|
147559
|
+
this.deleteStyle = output();
|
|
147560
|
+
/** A newly-created style, for a parent that wants to assign it to the table. */
|
|
147561
|
+
this.assignStyle = output();
|
|
147562
|
+
this.close = output();
|
|
147563
|
+
this.translate = inject(TranslateService);
|
|
147564
|
+
this.loader = inject(LoadContentService, { optional: true });
|
|
147565
|
+
this.parts = TABLE_STYLE_EDITOR_PARTS;
|
|
147566
|
+
this.selectedPart = signal('wholeTbl', /* @ts-ignore */
|
|
147567
|
+
...(ngDevMode ? [{ debugName: "selectedPart" }] : /* istanbul ignore next */ []));
|
|
147568
|
+
this.activeStyleId = signal('', /* @ts-ignore */
|
|
147569
|
+
...(ngDevMode ? [{ debugName: "activeStyleId" }] : /* istanbul ignore next */ []));
|
|
147570
|
+
this.entry = computed(() => {
|
|
147571
|
+
const id = this.activeStyleId() || (this.styleId() ? normalizeTableStyleGuid(this.styleId()) : '');
|
|
147572
|
+
return id ? this.styleMap()?.[id] : undefined;
|
|
147573
|
+
}, /* @ts-ignore */
|
|
147574
|
+
...(ngDevMode ? [{ debugName: "entry" }] : /* istanbul ignore next */ []));
|
|
147575
|
+
this.descriptor = computed(() => describeTableStyleEditor(this.entry(), this.selectedPart(), this.loader?.themeColorMap?.()), /* @ts-ignore */
|
|
147576
|
+
...(ngDevMode ? [{ debugName: "descriptor" }] : /* istanbul ignore next */ []));
|
|
147577
|
+
}
|
|
147578
|
+
onFieldEdit(fieldEdit) {
|
|
147579
|
+
const entry = this.entry();
|
|
147580
|
+
const map = this.styleMap();
|
|
147581
|
+
if (!entry || !map) {
|
|
147582
|
+
return;
|
|
147583
|
+
}
|
|
147584
|
+
const { entry: nextEntry } = applyTableStyleFieldEdit(entry, this.selectedPart(), fieldEdit);
|
|
147585
|
+
this.styleMapChange.emit({ ...map, [nextEntry.styleId]: nextEntry });
|
|
147586
|
+
}
|
|
147587
|
+
createFromCurrent() {
|
|
147588
|
+
const entry = this.entry();
|
|
147589
|
+
const name = window.prompt(this.translate.instant('pptx.tableStyleEditor.newStyleNamePrompt'), entry ? `${entry.styleName ?? ''} Copy`.trim() : '');
|
|
147590
|
+
if (!name) {
|
|
147591
|
+
return;
|
|
147592
|
+
}
|
|
147593
|
+
const nextMap = { ...(this.styleMap() ?? {}) };
|
|
147594
|
+
const created = createTableStyleEntry(nextMap, { styleName: name, basedOn: entry });
|
|
147595
|
+
addTableStyleToMap(nextMap, created);
|
|
147596
|
+
this.styleMapChange.emit(nextMap);
|
|
147597
|
+
this.activeStyleId.set(created.styleId);
|
|
147598
|
+
this.assignStyle.emit(created.styleId);
|
|
147599
|
+
}
|
|
147600
|
+
handleDelete() {
|
|
147601
|
+
const entry = this.entry();
|
|
147602
|
+
const map = this.styleMap();
|
|
147603
|
+
if (!entry ||
|
|
147604
|
+
!map ||
|
|
147605
|
+
!window.confirm(this.translate.instant('pptx.tableStyleEditor.deleteConfirm'))) {
|
|
147606
|
+
return;
|
|
147607
|
+
}
|
|
147608
|
+
const nextMap = { ...map };
|
|
147609
|
+
deleteTableStyleFromMap(nextMap, entry.styleId);
|
|
147610
|
+
this.styleMapChange.emit(nextMap);
|
|
147611
|
+
this.deleteStyle.emit(entry.styleId);
|
|
147612
|
+
this.close.emit();
|
|
147613
|
+
}
|
|
147614
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
147615
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TableStyleEditorComponent, isStandalone: true, selector: "pptx-table-style-editor", inputs: { styleMap: { classPropertyName: "styleMap", publicName: "styleMap", isSignal: true, isRequired: false, transformFunction: null }, styleId: { classPropertyName: "styleId", publicName: "styleId", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { styleMapChange: "styleMapChange", deleteStyle: "deleteStyle", assignStyle: "assignStyle", close: "close" }, ngImport: i0, template: `
|
|
147616
|
+
<div class="pptx-tse" data-testid="table-style-editor">
|
|
147617
|
+
<div class="pptx-tse__hdr">
|
|
147618
|
+
<div class="pptx-tse__hdg">{{ 'pptx.tableStyleEditor.title' | translate }}</div>
|
|
147619
|
+
<button type="button" class="pptx-tse__btn" (click)="close.emit()">
|
|
147620
|
+
{{ 'pptx.tableStyleEditor.close' | translate }}
|
|
147621
|
+
</button>
|
|
147622
|
+
</div>
|
|
147623
|
+
|
|
147624
|
+
@if (!entry()) {
|
|
147625
|
+
<div class="pptx-tse__empty">{{ 'pptx.tableStyleEditor.noStyleSelected' | translate }}</div>
|
|
147626
|
+
}
|
|
147627
|
+
|
|
147628
|
+
@if (entry()) {
|
|
147629
|
+
<div class="pptx-tse__parts">
|
|
147630
|
+
@for (part of parts; track part.id) {
|
|
147631
|
+
<button
|
|
147632
|
+
type="button"
|
|
147633
|
+
class="pptx-tse__btn"
|
|
147634
|
+
[class.pptx-tse__btn--active]="selectedPart() === part.id"
|
|
147635
|
+
[disabled]="!canEdit()"
|
|
147636
|
+
(click)="selectedPart.set(part.id)"
|
|
147637
|
+
>
|
|
147638
|
+
{{ part.labelKey | translate }}
|
|
147639
|
+
</button>
|
|
147640
|
+
}
|
|
147641
|
+
</div>
|
|
147642
|
+
}
|
|
147643
|
+
|
|
147644
|
+
@if (descriptor(); as d) {
|
|
147645
|
+
<pptx-table-style-editor-fields
|
|
147646
|
+
[descriptor]="d"
|
|
147647
|
+
[canEdit]="canEdit()"
|
|
147648
|
+
(edit)="onFieldEdit($event)"
|
|
147649
|
+
/>
|
|
147650
|
+
}
|
|
147651
|
+
|
|
147652
|
+
<div class="pptx-tse__actions">
|
|
147653
|
+
<button
|
|
147654
|
+
type="button"
|
|
147655
|
+
class="pptx-tse__btn"
|
|
147656
|
+
[disabled]="!canEdit()"
|
|
147657
|
+
(click)="createFromCurrent()"
|
|
147658
|
+
>
|
|
147659
|
+
{{
|
|
147660
|
+
(entry() ? 'pptx.tableStyleEditor.newFromCurrent' : 'pptx.tableStyleEditor.newStyle')
|
|
147661
|
+
| translate
|
|
147662
|
+
}}
|
|
147663
|
+
</button>
|
|
147664
|
+
@if (entry()) {
|
|
147665
|
+
<button
|
|
147666
|
+
type="button"
|
|
147667
|
+
class="pptx-tse__btn"
|
|
147668
|
+
[disabled]="!canEdit()"
|
|
147669
|
+
(click)="handleDelete()"
|
|
147670
|
+
>
|
|
147671
|
+
{{ 'pptx.tableStyleEditor.deleteStyle' | translate }}
|
|
147672
|
+
</button>
|
|
147673
|
+
}
|
|
147674
|
+
</div>
|
|
147675
|
+
</div>
|
|
147676
|
+
`, isInline: true, styles: [".pptx-tse{display:flex;flex-direction:column;gap:.5rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:4px;padding:.5rem}.pptx-tse__hdr{display:flex;align-items:center;justify-content:space-between}.pptx-tse__hdg{font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-inspector-muted, #888)}.pptx-tse__empty{font-size:11px;color:var(--pptx-inspector-muted, #888)}.pptx-tse__parts{display:flex;flex-wrap:wrap;gap:.25rem}.pptx-tse__actions{display:flex;gap:.4rem;padding-top:.25rem;border-top:1px solid var(--pptx-inspector-border, #444)}.pptx-tse__btn{font-size:11px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 6px;cursor:pointer}.pptx-tse__btn--active{background:var(--pptx-inspector-active, #3a3a3a)}.pptx-tse__btn:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: TableStyleEditorFieldsComponent, selector: "pptx-table-style-editor-fields", inputs: ["descriptor", "canEdit"], outputs: ["edit"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
147677
|
+
}
|
|
147678
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorComponent, decorators: [{
|
|
147679
|
+
type: Component,
|
|
147680
|
+
args: [{ selector: 'pptx-table-style-editor', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe, TableStyleEditorFieldsComponent], template: `
|
|
147681
|
+
<div class="pptx-tse" data-testid="table-style-editor">
|
|
147682
|
+
<div class="pptx-tse__hdr">
|
|
147683
|
+
<div class="pptx-tse__hdg">{{ 'pptx.tableStyleEditor.title' | translate }}</div>
|
|
147684
|
+
<button type="button" class="pptx-tse__btn" (click)="close.emit()">
|
|
147685
|
+
{{ 'pptx.tableStyleEditor.close' | translate }}
|
|
147686
|
+
</button>
|
|
147687
|
+
</div>
|
|
147688
|
+
|
|
147689
|
+
@if (!entry()) {
|
|
147690
|
+
<div class="pptx-tse__empty">{{ 'pptx.tableStyleEditor.noStyleSelected' | translate }}</div>
|
|
147691
|
+
}
|
|
147692
|
+
|
|
147693
|
+
@if (entry()) {
|
|
147694
|
+
<div class="pptx-tse__parts">
|
|
147695
|
+
@for (part of parts; track part.id) {
|
|
147696
|
+
<button
|
|
147697
|
+
type="button"
|
|
147698
|
+
class="pptx-tse__btn"
|
|
147699
|
+
[class.pptx-tse__btn--active]="selectedPart() === part.id"
|
|
147700
|
+
[disabled]="!canEdit()"
|
|
147701
|
+
(click)="selectedPart.set(part.id)"
|
|
147702
|
+
>
|
|
147703
|
+
{{ part.labelKey | translate }}
|
|
147704
|
+
</button>
|
|
147705
|
+
}
|
|
147706
|
+
</div>
|
|
147707
|
+
}
|
|
147708
|
+
|
|
147709
|
+
@if (descriptor(); as d) {
|
|
147710
|
+
<pptx-table-style-editor-fields
|
|
147711
|
+
[descriptor]="d"
|
|
147712
|
+
[canEdit]="canEdit()"
|
|
147713
|
+
(edit)="onFieldEdit($event)"
|
|
147714
|
+
/>
|
|
147715
|
+
}
|
|
147716
|
+
|
|
147717
|
+
<div class="pptx-tse__actions">
|
|
147718
|
+
<button
|
|
147719
|
+
type="button"
|
|
147720
|
+
class="pptx-tse__btn"
|
|
147721
|
+
[disabled]="!canEdit()"
|
|
147722
|
+
(click)="createFromCurrent()"
|
|
147723
|
+
>
|
|
147724
|
+
{{
|
|
147725
|
+
(entry() ? 'pptx.tableStyleEditor.newFromCurrent' : 'pptx.tableStyleEditor.newStyle')
|
|
147726
|
+
| translate
|
|
147727
|
+
}}
|
|
147728
|
+
</button>
|
|
147729
|
+
@if (entry()) {
|
|
147730
|
+
<button
|
|
147731
|
+
type="button"
|
|
147732
|
+
class="pptx-tse__btn"
|
|
147733
|
+
[disabled]="!canEdit()"
|
|
147734
|
+
(click)="handleDelete()"
|
|
147735
|
+
>
|
|
147736
|
+
{{ 'pptx.tableStyleEditor.deleteStyle' | translate }}
|
|
147737
|
+
</button>
|
|
147738
|
+
}
|
|
147739
|
+
</div>
|
|
147740
|
+
</div>
|
|
147741
|
+
`, styles: [".pptx-tse{display:flex;flex-direction:column;gap:.5rem;border:1px solid var(--pptx-inspector-border, #444);border-radius:4px;padding:.5rem}.pptx-tse__hdr{display:flex;align-items:center;justify-content:space-between}.pptx-tse__hdg{font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-inspector-muted, #888)}.pptx-tse__empty{font-size:11px;color:var(--pptx-inspector-muted, #888)}.pptx-tse__parts{display:flex;flex-wrap:wrap;gap:.25rem}.pptx-tse__actions{display:flex;gap:.4rem;padding-top:.25rem;border-top:1px solid var(--pptx-inspector-border, #444)}.pptx-tse__btn{font-size:11px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 6px;cursor:pointer}.pptx-tse__btn--active{background:var(--pptx-inspector-active, #3a3a3a)}.pptx-tse__btn:disabled{opacity:.4;cursor:not-allowed}\n"] }]
|
|
147742
|
+
}], propDecorators: { styleMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleMap", required: false }] }], styleId: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleId", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], styleMapChange: [{ type: i0.Output, args: ["styleMapChange"] }], deleteStyle: [{ type: i0.Output, args: ["deleteStyle"] }], assignStyle: [{ type: i0.Output, args: ["assignStyle"] }], close: [{ type: i0.Output, args: ["close"] }] } });
|
|
147743
|
+
|
|
147744
|
+
/**
|
|
147745
|
+
* table-style-editor-launcher.component.ts: the "Edit style..." button +
|
|
147746
|
+
* open/close state for `TableStyleEditorComponent`, extracted so
|
|
147747
|
+
* `TablePropertiesComponent` (already over this repo's 300-LOC file budget)
|
|
147748
|
+
* gains only a single wiring line rather than growing further.
|
|
147749
|
+
*
|
|
147750
|
+
* @module viewer/table-style-editor-launcher
|
|
147751
|
+
*/
|
|
147752
|
+
class TableStyleEditorLauncherComponent {
|
|
147753
|
+
constructor() {
|
|
147754
|
+
this.tableStyleMap = input(undefined, /* @ts-ignore */
|
|
147755
|
+
...(ngDevMode ? [{ debugName: "tableStyleMap" }] : /* istanbul ignore next */ []));
|
|
147756
|
+
this.styleId = input(undefined, /* @ts-ignore */
|
|
147757
|
+
...(ngDevMode ? [{ debugName: "styleId" }] : /* istanbul ignore next */ []));
|
|
147758
|
+
this.canEdit = input(true, /* @ts-ignore */
|
|
147759
|
+
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
147760
|
+
this.tableStyleMapChange = output();
|
|
147761
|
+
this.deleteTableStyle = output();
|
|
147762
|
+
/** A newly-created style, for a parent that wants to assign it to the table. */
|
|
147763
|
+
this.assignStyle = output();
|
|
147764
|
+
this.open = signal(false, /* @ts-ignore */
|
|
147765
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
147766
|
+
}
|
|
147767
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorLauncherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
147768
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TableStyleEditorLauncherComponent, isStandalone: true, selector: "pptx-table-style-editor-launcher", inputs: { tableStyleMap: { classPropertyName: "tableStyleMap", publicName: "tableStyleMap", isSignal: true, isRequired: false, transformFunction: null }, styleId: { classPropertyName: "styleId", publicName: "styleId", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableStyleMapChange: "tableStyleMapChange", deleteTableStyle: "deleteTableStyle", assignStyle: "assignStyle" }, ngImport: i0, template: `
|
|
147769
|
+
@if (tableStyleMap() !== undefined) {
|
|
147770
|
+
<button
|
|
147771
|
+
type="button"
|
|
147772
|
+
class="pptx-tsel__btn"
|
|
147773
|
+
[disabled]="!canEdit()"
|
|
147774
|
+
(click)="open.set(!open())"
|
|
147775
|
+
>
|
|
147776
|
+
{{ 'pptx.tableStyleEditor.editButton' | translate }}
|
|
147777
|
+
</button>
|
|
147778
|
+
|
|
147779
|
+
@if (open()) {
|
|
147780
|
+
<pptx-table-style-editor
|
|
147781
|
+
[styleMap]="tableStyleMap()"
|
|
147782
|
+
[styleId]="styleId()"
|
|
147783
|
+
[canEdit]="canEdit()"
|
|
147784
|
+
(styleMapChange)="tableStyleMapChange.emit($event)"
|
|
147785
|
+
(deleteStyle)="deleteTableStyle.emit($event)"
|
|
147786
|
+
(assignStyle)="assignStyle.emit($event)"
|
|
147787
|
+
(close)="open.set(false)"
|
|
147788
|
+
/>
|
|
147789
|
+
}
|
|
147790
|
+
}
|
|
147791
|
+
`, isInline: true, styles: [".pptx-tsel__btn{margin-top:.35rem;align-self:flex-start;font-size:11px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 6px;cursor:pointer}.pptx-tsel__btn:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: TableStyleEditorComponent, selector: "pptx-table-style-editor", inputs: ["styleMap", "styleId", "canEdit"], outputs: ["styleMapChange", "deleteStyle", "assignStyle", "close"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
147792
|
+
}
|
|
147793
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TableStyleEditorLauncherComponent, decorators: [{
|
|
147794
|
+
type: Component,
|
|
147795
|
+
args: [{ selector: 'pptx-table-style-editor-launcher', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe, TableStyleEditorComponent], template: `
|
|
147796
|
+
@if (tableStyleMap() !== undefined) {
|
|
147797
|
+
<button
|
|
147798
|
+
type="button"
|
|
147799
|
+
class="pptx-tsel__btn"
|
|
147800
|
+
[disabled]="!canEdit()"
|
|
147801
|
+
(click)="open.set(!open())"
|
|
147802
|
+
>
|
|
147803
|
+
{{ 'pptx.tableStyleEditor.editButton' | translate }}
|
|
147804
|
+
</button>
|
|
147805
|
+
|
|
147806
|
+
@if (open()) {
|
|
147807
|
+
<pptx-table-style-editor
|
|
147808
|
+
[styleMap]="tableStyleMap()"
|
|
147809
|
+
[styleId]="styleId()"
|
|
147810
|
+
[canEdit]="canEdit()"
|
|
147811
|
+
(styleMapChange)="tableStyleMapChange.emit($event)"
|
|
147812
|
+
(deleteStyle)="deleteTableStyle.emit($event)"
|
|
147813
|
+
(assignStyle)="assignStyle.emit($event)"
|
|
147814
|
+
(close)="open.set(false)"
|
|
147815
|
+
/>
|
|
147816
|
+
}
|
|
147817
|
+
}
|
|
147818
|
+
`, styles: [".pptx-tsel__btn{margin-top:.35rem;align-self:flex-start;font-size:11px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 6px;cursor:pointer}.pptx-tsel__btn:disabled{opacity:.4;cursor:not-allowed}\n"] }]
|
|
147819
|
+
}], propDecorators: { tableStyleMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableStyleMap", required: false }] }], styleId: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleId", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], tableStyleMapChange: [{ type: i0.Output, args: ["tableStyleMapChange"] }], deleteTableStyle: [{ type: i0.Output, args: ["deleteTableStyle"] }], assignStyle: [{ type: i0.Output, args: ["assignStyle"] }] } });
|
|
147820
|
+
|
|
145658
147821
|
/**
|
|
145659
147822
|
* table-properties.component.ts: table-level style inspector.
|
|
145660
147823
|
*
|
|
@@ -145679,6 +147842,16 @@ class TablePropertiesComponent {
|
|
|
145679
147842
|
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
145680
147843
|
/** Emits the fully-updated element after any edit. */
|
|
145681
147844
|
this.elementChange = output();
|
|
147845
|
+
/**
|
|
147846
|
+
* The deck's parsed `ppt/tableStyles.xml` map, for "Edit style...". `undefined`
|
|
147847
|
+
* means the host has not wired the table-style-editor feature through; the
|
|
147848
|
+
* launcher then simply does not render its button.
|
|
147849
|
+
*/
|
|
147850
|
+
this.tableStyleMap = input(undefined, /* @ts-ignore */
|
|
147851
|
+
...(ngDevMode ? [{ debugName: "tableStyleMap" }] : /* istanbul ignore next */ []));
|
|
147852
|
+
this.tableStyleMapChange = output();
|
|
147853
|
+
/** Record a styleId for save-time removal from `ppt/tableStyles.xml`. */
|
|
147854
|
+
this.deleteTableStyle = output();
|
|
145682
147855
|
this.toggles = TABLE_STRUCTURE_TOGGLES;
|
|
145683
147856
|
this.presets = TABLE_STYLE_PRESETS;
|
|
145684
147857
|
this.defaultRowHeight = DEFAULT_TABLE_ROW_HEIGHT;
|
|
@@ -145735,11 +147908,15 @@ class TablePropertiesComponent {
|
|
|
145735
147908
|
const rows = data.rows.map((r, i) => (i === index ? { ...r, height: n } : r));
|
|
145736
147909
|
this.emit({ rows });
|
|
145737
147910
|
}
|
|
147911
|
+
/** A newly-created style (from "Edit style...") becomes this table's style. */
|
|
147912
|
+
onAssignStyle(styleId) {
|
|
147913
|
+
this.emit(tableStyleAssignmentUpdate(styleId));
|
|
147914
|
+
}
|
|
145738
147915
|
emit(patch) {
|
|
145739
147916
|
this.elementChange.emit(patchTableData(this.element(), patch));
|
|
145740
147917
|
}
|
|
145741
147918
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TablePropertiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
145742
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TablePropertiesComponent, isStandalone: true, selector: "pptx-table-properties", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementChange: "elementChange" }, ngImport: i0, template: `
|
|
147919
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TablePropertiesComponent, isStandalone: true, selector: "pptx-table-properties", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, tableStyleMap: { classPropertyName: "tableStyleMap", publicName: "tableStyleMap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementChange: "elementChange", tableStyleMapChange: "tableStyleMapChange", deleteTableStyle: "deleteTableStyle" }, ngImport: i0, template: `
|
|
145743
147920
|
@if (td(); as data) {
|
|
145744
147921
|
<div class="pptx-tp">
|
|
145745
147922
|
<div class="pptx-tp__dims">{{ data.rows.length }} rows × {{ colCount() }} cols</div>
|
|
@@ -145803,6 +147980,14 @@ class TablePropertiesComponent {
|
|
|
145803
147980
|
</button>
|
|
145804
147981
|
}
|
|
145805
147982
|
</div>
|
|
147983
|
+
<pptx-table-style-editor-launcher
|
|
147984
|
+
[tableStyleMap]="tableStyleMap()"
|
|
147985
|
+
[styleId]="data.tableStyleId"
|
|
147986
|
+
[canEdit]="canEdit()"
|
|
147987
|
+
(tableStyleMapChange)="tableStyleMapChange.emit($event)"
|
|
147988
|
+
(deleteTableStyle)="deleteTableStyle.emit($event)"
|
|
147989
|
+
(assignStyle)="onAssignStyle($event)"
|
|
147990
|
+
/>
|
|
145806
147991
|
|
|
145807
147992
|
<div class="pptx-tp__row-head">
|
|
145808
147993
|
<span class="pptx-tp__lbl">{{ 'pptx.table.columnWidths' | translate }}</span>
|
|
@@ -145859,11 +148044,11 @@ class TablePropertiesComponent {
|
|
|
145859
148044
|
}
|
|
145860
148045
|
</div>
|
|
145861
148046
|
}
|
|
145862
|
-
`, isInline: true, styles: [".pptx-tp{display:flex;flex-direction:column;gap:.35rem}.pptx-tp__dims{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__toggles{display:flex;flex-direction:column;gap:.2rem}.pptx-tp__check{display:flex;align-items:center;gap:.4rem;font-size:11px;cursor:pointer}.pptx-tp__field{display:flex;align-items:center;gap:.35rem;font-size:11px}.pptx-tp__row-head{display:flex;align-items:center;justify-content:space-between}.pptx-tp__lbl{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__idx{width:1.2rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__num{width:3.5rem;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 4px;font-size:11px}.pptx-tp__range{flex:1;min-width:0}.pptx-tp__pct{width:2.5rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__even{font-size:10px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:1px 6px;cursor:pointer}.pptx-tp__presets{display:grid;grid-template-columns:repeat(3,1fr);gap:.3rem}.pptx-tp__preset{display:flex;flex-direction:column;height:2.5rem;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;overflow:hidden;cursor:pointer}.pptx-tp__preset:disabled{opacity:.4;cursor:not-allowed}.pptx-tp__swatch{flex:1;display:block}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
148047
|
+
`, isInline: true, styles: [".pptx-tp{display:flex;flex-direction:column;gap:.35rem}.pptx-tp__dims{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__toggles{display:flex;flex-direction:column;gap:.2rem}.pptx-tp__check{display:flex;align-items:center;gap:.4rem;font-size:11px;cursor:pointer}.pptx-tp__field{display:flex;align-items:center;gap:.35rem;font-size:11px}.pptx-tp__row-head{display:flex;align-items:center;justify-content:space-between}.pptx-tp__lbl{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__idx{width:1.2rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__num{width:3.5rem;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 4px;font-size:11px}.pptx-tp__range{flex:1;min-width:0}.pptx-tp__pct{width:2.5rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__even{font-size:10px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:1px 6px;cursor:pointer}.pptx-tp__presets{display:grid;grid-template-columns:repeat(3,1fr);gap:.3rem}.pptx-tp__preset{display:flex;flex-direction:column;height:2.5rem;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;overflow:hidden;cursor:pointer}.pptx-tp__preset:disabled{opacity:.4;cursor:not-allowed}.pptx-tp__swatch{flex:1;display:block}\n"], dependencies: [{ kind: "component", type: TableStyleEditorLauncherComponent, selector: "pptx-table-style-editor-launcher", inputs: ["tableStyleMap", "styleId", "canEdit"], outputs: ["tableStyleMapChange", "deleteTableStyle", "assignStyle"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
145863
148048
|
}
|
|
145864
148049
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TablePropertiesComponent, decorators: [{
|
|
145865
148050
|
type: Component,
|
|
145866
|
-
args: [{ selector: 'pptx-table-properties', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
|
|
148051
|
+
args: [{ selector: 'pptx-table-properties', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe, TableStyleEditorLauncherComponent], template: `
|
|
145867
148052
|
@if (td(); as data) {
|
|
145868
148053
|
<div class="pptx-tp">
|
|
145869
148054
|
<div class="pptx-tp__dims">{{ data.rows.length }} rows × {{ colCount() }} cols</div>
|
|
@@ -145927,6 +148112,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
145927
148112
|
</button>
|
|
145928
148113
|
}
|
|
145929
148114
|
</div>
|
|
148115
|
+
<pptx-table-style-editor-launcher
|
|
148116
|
+
[tableStyleMap]="tableStyleMap()"
|
|
148117
|
+
[styleId]="data.tableStyleId"
|
|
148118
|
+
[canEdit]="canEdit()"
|
|
148119
|
+
(tableStyleMapChange)="tableStyleMapChange.emit($event)"
|
|
148120
|
+
(deleteTableStyle)="deleteTableStyle.emit($event)"
|
|
148121
|
+
(assignStyle)="onAssignStyle($event)"
|
|
148122
|
+
/>
|
|
145930
148123
|
|
|
145931
148124
|
<div class="pptx-tp__row-head">
|
|
145932
148125
|
<span class="pptx-tp__lbl">{{ 'pptx.table.columnWidths' | translate }}</span>
|
|
@@ -145984,7 +148177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
145984
148177
|
</div>
|
|
145985
148178
|
}
|
|
145986
148179
|
`, styles: [".pptx-tp{display:flex;flex-direction:column;gap:.35rem}.pptx-tp__dims{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__toggles{display:flex;flex-direction:column;gap:.2rem}.pptx-tp__check{display:flex;align-items:center;gap:.4rem;font-size:11px;cursor:pointer}.pptx-tp__field{display:flex;align-items:center;gap:.35rem;font-size:11px}.pptx-tp__row-head{display:flex;align-items:center;justify-content:space-between}.pptx-tp__lbl{font-size:10px;color:var(--pptx-inspector-muted, #888)}.pptx-tp__idx{width:1.2rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__num{width:3.5rem;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 4px;font-size:11px}.pptx-tp__range{flex:1;min-width:0}.pptx-tp__pct{width:2.5rem;text-align:right;color:var(--pptx-inspector-muted, #888)}.pptx-tp__even{font-size:10px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:1px 6px;cursor:pointer}.pptx-tp__presets{display:grid;grid-template-columns:repeat(3,1fr);gap:.3rem}.pptx-tp__preset{display:flex;flex-direction:column;height:2.5rem;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;overflow:hidden;cursor:pointer}.pptx-tp__preset:disabled{opacity:.4;cursor:not-allowed}.pptx-tp__swatch{flex:1;display:block}\n"] }]
|
|
145987
|
-
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], elementChange: [{ type: i0.Output, args: ["elementChange"] }] } });
|
|
148180
|
+
}], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], elementChange: [{ type: i0.Output, args: ["elementChange"] }], tableStyleMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableStyleMap", required: false }] }], tableStyleMapChange: [{ type: i0.Output, args: ["tableStyleMapChange"] }], deleteTableStyle: [{ type: i0.Output, args: ["deleteTableStyle"] }] } });
|
|
145988
148181
|
function numberFrom(event) {
|
|
145989
148182
|
const t = event.target;
|
|
145990
148183
|
if (!(t instanceof HTMLInputElement)) {
|
|
@@ -147131,6 +149324,12 @@ class InspectorPanelComponent {
|
|
|
147131
149324
|
this.canEdit = input(true, /* @ts-ignore */
|
|
147132
149325
|
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
147133
149326
|
this.editor = inject(EditorStateService);
|
|
149327
|
+
/**
|
|
149328
|
+
* Optional: absent in a standalone-thumbnail/export render context.
|
|
149329
|
+
* Feeds the table properties panel's "Edit style..." (`tableStyleMap`),
|
|
149330
|
+
* see {@link onTableStyleMapChange} / {@link onDeleteTableStyle}.
|
|
149331
|
+
*/
|
|
149332
|
+
this.loader = inject(LoadContentService, { optional: true });
|
|
147134
149333
|
/** Reactive viewport / pointer flags (drives the bottom-sheet layout). */
|
|
147135
149334
|
this.mobile = inject(IsMobileService);
|
|
147136
149335
|
/** "Recent colours" row backing the fill/stroke/text colour pickers below. */
|
|
@@ -147235,6 +149434,17 @@ class InspectorPanelComponent {
|
|
|
147235
149434
|
...(ngDevMode ? [{ debugName: "chartEl" }] : /* istanbul ignore next */ []));
|
|
147236
149435
|
this.imageEl = computed(() => ImagePropertiesPanelComponent.supports(this.el()) ? this.el() : undefined, /* @ts-ignore */
|
|
147237
149436
|
...(ngDevMode ? [{ debugName: "imageEl" }] : /* istanbul ignore next */ []));
|
|
149437
|
+
/**
|
|
149438
|
+
* The selected element narrowed to a plain shape/text box/connector, or
|
|
149439
|
+
* `undefined`. Gates `AccessibilityTextPanelComponent` (alt text / title):
|
|
149440
|
+
* a picture's own alt text lives in `imageEl` above, so this must not
|
|
149441
|
+
* also match `image`/`picture`, and stays restricted to the three kinds
|
|
149442
|
+
* `PptxNonVisualDescription` was added to (not every graphic-frame kind
|
|
149443
|
+
* the shared descriptor recognises), so it does not duplicate a
|
|
149444
|
+
* table/chart/smartArt/media/ole panel's own alt-text UI.
|
|
149445
|
+
*/
|
|
149446
|
+
this.accessibilityTextEl = computed(() => AccessibilityTextPanelComponent.supports(this.el()) ? this.el() : undefined, /* @ts-ignore */
|
|
149447
|
+
...(ngDevMode ? [{ debugName: "accessibilityTextEl" }] : /* istanbul ignore next */ []));
|
|
147238
149448
|
this.mediaEl = computed(() => this.el().type === 'media' ? this.el() : undefined, /* @ts-ignore */
|
|
147239
149449
|
...(ngDevMode ? [{ debugName: "mediaEl" }] : /* istanbul ignore next */ []));
|
|
147240
149450
|
/** The selected element narrowed to SmartArt, or undefined. */
|
|
@@ -147281,6 +149491,40 @@ class InspectorPanelComponent {
|
|
|
147281
149491
|
onElementReplace(updated) {
|
|
147282
149492
|
this.editor.updateElement(this.slideIndex(), updated.id, updated);
|
|
147283
149493
|
}
|
|
149494
|
+
/**
|
|
149495
|
+
* Table style DEFINITION edits ("Edit style...") are a whole-map
|
|
149496
|
+
* replacement or a delete, never a per-element patch, so they bypass
|
|
149497
|
+
* {@link onElementReplace} entirely and write straight to the loader's
|
|
149498
|
+
* `tableStyleMap`/`tableStylesToDelete` signals. `applyTableStyleMapChange`/
|
|
149499
|
+
* `applyTableStyleDelete` (shared) keep `tableStylesToDelete` in sync, the
|
|
149500
|
+
* accumulator {@link LoadContentService.saveSlides} forwards via
|
|
149501
|
+
* `tableStyleSaveOptions`.
|
|
149502
|
+
*/
|
|
149503
|
+
onTableStyleMapChange(nextMap) {
|
|
149504
|
+
if (!this.loader) {
|
|
149505
|
+
return;
|
|
149506
|
+
}
|
|
149507
|
+
const result = applyTableStyleMapChange({
|
|
149508
|
+
tableStyleMap: this.loader.tableStyleMap(),
|
|
149509
|
+
tableStylesToDelete: this.loader.tableStylesToDelete(),
|
|
149510
|
+
}, nextMap);
|
|
149511
|
+
this.loader.tableStyleMap.set(result.tableStyleMap);
|
|
149512
|
+
this.loader.tableStylesToDelete.set(result.tableStylesToDelete);
|
|
149513
|
+
this.editor.dirty.set(true);
|
|
149514
|
+
}
|
|
149515
|
+
/** Record a styleId for save-time removal from `ppt/tableStyles.xml`. */
|
|
149516
|
+
onDeleteTableStyle(styleId) {
|
|
149517
|
+
if (!this.loader) {
|
|
149518
|
+
return;
|
|
149519
|
+
}
|
|
149520
|
+
const result = applyTableStyleDelete({
|
|
149521
|
+
tableStyleMap: this.loader.tableStyleMap(),
|
|
149522
|
+
tableStylesToDelete: this.loader.tableStylesToDelete(),
|
|
149523
|
+
}, styleId);
|
|
149524
|
+
this.loader.tableStyleMap.set(result.tableStyleMap);
|
|
149525
|
+
this.loader.tableStylesToDelete.set(result.tableStylesToDelete);
|
|
149526
|
+
this.editor.dirty.set(true);
|
|
149527
|
+
}
|
|
147284
149528
|
/** Commit an updated slide-level animation list as one history entry. */
|
|
147285
149529
|
onAnimationsChange(animations) {
|
|
147286
149530
|
this.editor.updateSlide(this.slideIndex(), { animations });
|
|
@@ -147670,6 +149914,15 @@ class InspectorPanelComponent {
|
|
|
147670
149914
|
</details>
|
|
147671
149915
|
}
|
|
147672
149916
|
|
|
149917
|
+
@if (accessibilityTextEl(); as a11yEl) {
|
|
149918
|
+
<details class="pptx-ng-inspector__details" open>
|
|
149919
|
+
<summary class="pptx-ng-inspector__summary">
|
|
149920
|
+
{{ 'pptx.accessibility.heading' | translate }}
|
|
149921
|
+
</summary>
|
|
149922
|
+
<pptx-accessibility-text-panel [element]="a11yEl" (patch)="onPatch($event)" />
|
|
149923
|
+
</details>
|
|
149924
|
+
}
|
|
149925
|
+
|
|
147673
149926
|
<!-- ── Arrange ────────────────────────────────────────────────────── -->
|
|
147674
149927
|
<section class="pptx-ng-inspector__section">
|
|
147675
149928
|
<div
|
|
@@ -147781,7 +150034,8 @@ class InspectorPanelComponent {
|
|
|
147781
150034
|
|
|
147782
150035
|
<!-- ── Table data editor ──────────────────────────────────────────── -->
|
|
147783
150036
|
@if (tableEl(); as t) {
|
|
147784
|
-
|
|
150037
|
+
<!-- Open by default, as the other four bindings show these two sections. -->
|
|
150038
|
+
<details class="pptx-ng-inspector__details" open>
|
|
147785
150039
|
<summary class="pptx-ng-inspector__summary">
|
|
147786
150040
|
{{ 'pptx.inspector.tableData' | translate }}
|
|
147787
150041
|
</summary>
|
|
@@ -147789,11 +150043,17 @@ class InspectorPanelComponent {
|
|
|
147789
150043
|
</details>
|
|
147790
150044
|
|
|
147791
150045
|
<!-- ── Table style (structure, presets, widths, heights) ─────────── -->
|
|
147792
|
-
<details class="pptx-ng-inspector__details">
|
|
150046
|
+
<details class="pptx-ng-inspector__details" open>
|
|
147793
150047
|
<summary class="pptx-ng-inspector__summary">
|
|
147794
150048
|
{{ 'pptx.inspector.tableStyle' | translate }}
|
|
147795
150049
|
</summary>
|
|
147796
|
-
<pptx-table-properties
|
|
150050
|
+
<pptx-table-properties
|
|
150051
|
+
[element]="t"
|
|
150052
|
+
[tableStyleMap]="loader?.tableStyleMap()"
|
|
150053
|
+
(elementChange)="onElementReplace($event)"
|
|
150054
|
+
(tableStyleMapChange)="onTableStyleMapChange($event)"
|
|
150055
|
+
(deleteTableStyle)="onDeleteTableStyle($event)"
|
|
150056
|
+
/>
|
|
147797
150057
|
</details>
|
|
147798
150058
|
|
|
147799
150059
|
<!-- ── Selected cell formatting ─────────────────────────────────── -->
|
|
@@ -147886,11 +150146,12 @@ class InspectorPanelComponent {
|
|
|
147886
150146
|
</div>
|
|
147887
150147
|
</section>
|
|
147888
150148
|
</aside>
|
|
147889
|
-
`, isInline: true, styles: [".pptx-ng-inspector{display:flex;flex-direction:column;gap:0;padding:.5rem;background:var(--pptx-inspector-bg, #1e1e1e);color:var(--pptx-inspector-fg, #e0e0e0);font-size:12px;min-width:220px;overflow-y:auto}.pptx-ng-inspector__section{padding:.5rem 0;border-bottom:1px solid var(--pptx-inspector-border, #333)}.pptx-ng-inspector__section:last-child{border-bottom:none}.pptx-ng-inspector__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0 0 .35rem}.pptx-ng-inspector__details{border-bottom:1px solid var(--pptx-inspector-border, #333)}.pptx-ng-inspector__summary{padding:.5rem 0;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-inspector__row{display:flex;align-items:center;gap:.35rem;margin-bottom:.35rem}.pptx-ng-inspector__row:last-child{margin-bottom:0}.pptx-ng-inspector__row--toggles{gap:.25rem}.pptx-ng-inspector__label{font-size:10px;color:var(--pptx-inspector-muted, #888);min-width:32px;text-align:right;flex-shrink:0}.pptx-ng-inspector__input{background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 4px;font-size:12px}.pptx-ng-inspector__input--number{width:62px;text-align:right}.pptx-ng-inspector__color{width:32px;height:22px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;padding:1px;cursor:pointer;background:transparent;flex-shrink:0}.pptx-ng-inspector__toggle{width:26px;height:22px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px}.pptx-ng-inspector.is-mobile{width:100%;min-width:0;box-sizing:border-box;font-size:14px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__row{flex-wrap:wrap;gap:.5rem}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__label{min-width:28px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__input{flex:1 1 auto;min-height:40px;font-size:16px;padding:6px 8px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__input--number{width:auto;min-width:72px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__color{width:44px;height:40px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__toggle{min-width:44px;width:auto;flex:1 1 auto;height:40px;font-size:15px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__btn{min-height:40px;padding:8px 10px;font-size:13px}@media(pointer:coarse),(max-width:767px){.pptx-ng-inspector{width:100%;min-width:0;box-sizing:border-box;font-size:14px}.pptx-ng-inspector__row{flex-wrap:wrap;gap:.5rem}.pptx-ng-inspector__label{min-width:28px}.pptx-ng-inspector__input{flex:1 1 auto;min-height:40px;font-size:16px;padding:6px 8px}.pptx-ng-inspector__input--number{width:auto;min-width:72px}.pptx-ng-inspector__color{width:44px;height:40px}.pptx-ng-inspector__toggle{min-width:44px;width:auto;flex:1 1 auto;height:40px;font-size:15px}.pptx-ng-inspector__btn{min-height:40px;padding:8px 10px;font-size:13px}}.pptx-ng-inspector__toggle.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}.pptx-ng-inspector__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.pptx-ng-inspector__btn:hover{background:var(--pptx-inspector-hover, #3a3a3a)}.pptx-ng-inspector__btn--danger{color:var(--pptx-inspector-danger, #f47c7c);border-color:var(--pptx-inspector-danger-border, #6b2a2a)}.pptx-ng-inspector__btn--danger:hover{background:var(--pptx-inspector-danger-hover, #4a1a1a)}\n"], dependencies: [{ kind: "component", type: GradientPickerComponent, selector: "pptx-gradient-picker", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: EffectsPanelComponent, selector: "pptx-effects-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: LineFormatPanelComponent, selector: "pptx-line-format-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: PatternFillPanelComponent, selector: "pptx-pattern-fill-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TextAdvancedPanelComponent, selector: "pptx-text-advanced-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TableDataEditorComponent, selector: "pptx-table-data-editor", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: TablePropertiesComponent, selector: "pptx-table-properties", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: TableCellFormattingComponent, selector: "pptx-table-cell-formatting", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: ChartDataEditorComponent, selector: "pptx-chart-data-editor", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: ChartTypeSelectorComponent, selector: "pptx-chart-type-selector", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: SmartArtPropertiesComponent, selector: "pptx-smart-art-properties", inputs: ["smartArtData", "canEdit"], outputs: ["smartArtDataChange"] }, { kind: "component", type: AnimationAuthorPanelComponent, selector: "pptx-animation-author-panel", inputs: ["element", "slideIndex", "animations", "slideElements", "animationTimelineAnchors", "canEdit"], outputs: ["animationsChange"] }, { kind: "component", type: ActionSettingsPanelComponent, selector: "pptx-action-settings-panel", inputs: ["element", "slideCount"], outputs: ["patch"] }, { kind: "component", type: ImagePropertiesPanelComponent, selector: "pptx-image-properties-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: MediaPropertiesPanelComponent, selector: "pptx-media-properties-panel", inputs: ["element", "canEdit"], outputs: ["patch"] }, { kind: "component", type: ElementMiscPropertiesComponent, selector: "pptx-element-misc-properties", inputs: ["element", "canEdit"], outputs: ["patch"] }, { kind: "component", type: ElementFlipControlsComponent, selector: "pptx-element-flip-controls", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: ShapeAuthoringPanelComponent, selector: "pptx-shape-authoring-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: Text3DPanelComponent, selector: "pptx-text-3d-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TextWarpGalleryComponent, selector: "pptx-text-warp-gallery", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: RecentColorsRowComponent, selector: "pptx-recent-colors-row", inputs: ["colors", "disabled"], outputs: ["pick"] }, { kind: "component", type: ThemeColorSwatchGridComponent, selector: "pptx-theme-color-swatch-grid", inputs: ["disabled", "selectedRef", "selectedHex"], outputs: ["pick"] }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
150149
|
+
`, isInline: true, styles: [".pptx-ng-inspector{display:flex;flex-direction:column;gap:0;padding:.5rem;background:var(--pptx-inspector-bg, #1e1e1e);color:var(--pptx-inspector-fg, #e0e0e0);font-size:12px;min-width:220px;overflow-y:auto}.pptx-ng-inspector__section{padding:.5rem 0;border-bottom:1px solid var(--pptx-inspector-border, #333)}.pptx-ng-inspector__section:last-child{border-bottom:none}.pptx-ng-inspector__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0 0 .35rem}.pptx-ng-inspector__details{border-bottom:1px solid var(--pptx-inspector-border, #333)}.pptx-ng-inspector__summary{padding:.5rem 0;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-inspector__row{display:flex;align-items:center;gap:.35rem;margin-bottom:.35rem}.pptx-ng-inspector__row:last-child{margin-bottom:0}.pptx-ng-inspector__row--toggles{gap:.25rem}.pptx-ng-inspector__label{font-size:10px;color:var(--pptx-inspector-muted, #888);min-width:32px;text-align:right;flex-shrink:0}.pptx-ng-inspector__input{background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:2px 4px;font-size:12px}.pptx-ng-inspector__input--number{width:62px;text-align:right}.pptx-ng-inspector__color{width:32px;height:22px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;padding:1px;cursor:pointer;background:transparent;flex-shrink:0}.pptx-ng-inspector__toggle{width:26px;height:22px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px}.pptx-ng-inspector.is-mobile{width:100%;min-width:0;box-sizing:border-box;font-size:14px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__row{flex-wrap:wrap;gap:.5rem}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__label{min-width:28px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__input{flex:1 1 auto;min-height:40px;font-size:16px;padding:6px 8px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__input--number{width:auto;min-width:72px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__color{width:44px;height:40px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__toggle{min-width:44px;width:auto;flex:1 1 auto;height:40px;font-size:15px}.pptx-ng-inspector.is-mobile .pptx-ng-inspector__btn{min-height:40px;padding:8px 10px;font-size:13px}@media(pointer:coarse),(max-width:767px){.pptx-ng-inspector{width:100%;min-width:0;box-sizing:border-box;font-size:14px}.pptx-ng-inspector__row{flex-wrap:wrap;gap:.5rem}.pptx-ng-inspector__label{min-width:28px}.pptx-ng-inspector__input{flex:1 1 auto;min-height:40px;font-size:16px;padding:6px 8px}.pptx-ng-inspector__input--number{width:auto;min-width:72px}.pptx-ng-inspector__color{width:44px;height:40px}.pptx-ng-inspector__toggle{min-width:44px;width:auto;flex:1 1 auto;height:40px;font-size:15px}.pptx-ng-inspector__btn{min-height:40px;padding:8px 10px;font-size:13px}}.pptx-ng-inspector__toggle.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}.pptx-ng-inspector__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, #2d2d2d);border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.pptx-ng-inspector__btn:hover{background:var(--pptx-inspector-hover, #3a3a3a)}.pptx-ng-inspector__btn--danger{color:var(--pptx-inspector-danger, #f47c7c);border-color:var(--pptx-inspector-danger-border, #6b2a2a)}.pptx-ng-inspector__btn--danger:hover{background:var(--pptx-inspector-danger-hover, #4a1a1a)}\n"], dependencies: [{ kind: "component", type: AccessibilityTextPanelComponent, selector: "pptx-accessibility-text-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: GradientPickerComponent, selector: "pptx-gradient-picker", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: EffectsPanelComponent, selector: "pptx-effects-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: LineFormatPanelComponent, selector: "pptx-line-format-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: PatternFillPanelComponent, selector: "pptx-pattern-fill-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TextAdvancedPanelComponent, selector: "pptx-text-advanced-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TableDataEditorComponent, selector: "pptx-table-data-editor", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: TablePropertiesComponent, selector: "pptx-table-properties", inputs: ["element", "canEdit", "tableStyleMap"], outputs: ["elementChange", "tableStyleMapChange", "deleteTableStyle"] }, { kind: "component", type: TableCellFormattingComponent, selector: "pptx-table-cell-formatting", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: ChartDataEditorComponent, selector: "pptx-chart-data-editor", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: ChartTypeSelectorComponent, selector: "pptx-chart-type-selector", inputs: ["element", "canEdit"], outputs: ["elementChange"] }, { kind: "component", type: SmartArtPropertiesComponent, selector: "pptx-smart-art-properties", inputs: ["smartArtData", "canEdit"], outputs: ["smartArtDataChange"] }, { kind: "component", type: AnimationAuthorPanelComponent, selector: "pptx-animation-author-panel", inputs: ["element", "slideIndex", "animations", "slideElements", "animationTimelineAnchors", "canEdit"], outputs: ["animationsChange"] }, { kind: "component", type: ActionSettingsPanelComponent, selector: "pptx-action-settings-panel", inputs: ["element", "slideCount"], outputs: ["patch"] }, { kind: "component", type: ImagePropertiesPanelComponent, selector: "pptx-image-properties-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: MediaPropertiesPanelComponent, selector: "pptx-media-properties-panel", inputs: ["element", "canEdit"], outputs: ["patch"] }, { kind: "component", type: ElementMiscPropertiesComponent, selector: "pptx-element-misc-properties", inputs: ["element", "canEdit"], outputs: ["patch"] }, { kind: "component", type: ElementFlipControlsComponent, selector: "pptx-element-flip-controls", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: ShapeAuthoringPanelComponent, selector: "pptx-shape-authoring-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: Text3DPanelComponent, selector: "pptx-text-3d-panel", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: TextWarpGalleryComponent, selector: "pptx-text-warp-gallery", inputs: ["element"], outputs: ["patch"] }, { kind: "component", type: RecentColorsRowComponent, selector: "pptx-recent-colors-row", inputs: ["colors", "disabled"], outputs: ["pick"] }, { kind: "component", type: ThemeColorSwatchGridComponent, selector: "pptx-theme-color-swatch-grid", inputs: ["disabled", "selectedRef", "selectedHex"], outputs: ["pick"] }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
147890
150150
|
}
|
|
147891
150151
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: InspectorPanelComponent, decorators: [{
|
|
147892
150152
|
type: Component,
|
|
147893
150153
|
args: [{ selector: 'pptx-inspector-panel', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
150154
|
+
AccessibilityTextPanelComponent,
|
|
147894
150155
|
GradientPickerComponent,
|
|
147895
150156
|
EffectsPanelComponent,
|
|
147896
150157
|
LineFormatPanelComponent,
|
|
@@ -148177,6 +150438,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
148177
150438
|
</details>
|
|
148178
150439
|
}
|
|
148179
150440
|
|
|
150441
|
+
@if (accessibilityTextEl(); as a11yEl) {
|
|
150442
|
+
<details class="pptx-ng-inspector__details" open>
|
|
150443
|
+
<summary class="pptx-ng-inspector__summary">
|
|
150444
|
+
{{ 'pptx.accessibility.heading' | translate }}
|
|
150445
|
+
</summary>
|
|
150446
|
+
<pptx-accessibility-text-panel [element]="a11yEl" (patch)="onPatch($event)" />
|
|
150447
|
+
</details>
|
|
150448
|
+
}
|
|
150449
|
+
|
|
148180
150450
|
<!-- ── Arrange ────────────────────────────────────────────────────── -->
|
|
148181
150451
|
<section class="pptx-ng-inspector__section">
|
|
148182
150452
|
<div
|
|
@@ -148288,7 +150558,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
148288
150558
|
|
|
148289
150559
|
<!-- ── Table data editor ──────────────────────────────────────────── -->
|
|
148290
150560
|
@if (tableEl(); as t) {
|
|
148291
|
-
|
|
150561
|
+
<!-- Open by default, as the other four bindings show these two sections. -->
|
|
150562
|
+
<details class="pptx-ng-inspector__details" open>
|
|
148292
150563
|
<summary class="pptx-ng-inspector__summary">
|
|
148293
150564
|
{{ 'pptx.inspector.tableData' | translate }}
|
|
148294
150565
|
</summary>
|
|
@@ -148296,11 +150567,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
148296
150567
|
</details>
|
|
148297
150568
|
|
|
148298
150569
|
<!-- ── Table style (structure, presets, widths, heights) ─────────── -->
|
|
148299
|
-
<details class="pptx-ng-inspector__details">
|
|
150570
|
+
<details class="pptx-ng-inspector__details" open>
|
|
148300
150571
|
<summary class="pptx-ng-inspector__summary">
|
|
148301
150572
|
{{ 'pptx.inspector.tableStyle' | translate }}
|
|
148302
150573
|
</summary>
|
|
148303
|
-
<pptx-table-properties
|
|
150574
|
+
<pptx-table-properties
|
|
150575
|
+
[element]="t"
|
|
150576
|
+
[tableStyleMap]="loader?.tableStyleMap()"
|
|
150577
|
+
(elementChange)="onElementReplace($event)"
|
|
150578
|
+
(tableStyleMapChange)="onTableStyleMapChange($event)"
|
|
150579
|
+
(deleteTableStyle)="onDeleteTableStyle($event)"
|
|
150580
|
+
/>
|
|
148304
150581
|
</details>
|
|
148305
150582
|
|
|
148306
150583
|
<!-- ── Selected cell formatting ─────────────────────────────────── -->
|
|
@@ -159028,6 +161305,10 @@ class PowerPointViewerComponent {
|
|
|
159028
161305
|
getCustomProperties: () => this.loader.customProperties(),
|
|
159029
161306
|
getCoreProperties: () => this.loader.coreProperties(),
|
|
159030
161307
|
getAppProperties: () => this.loader.appProperties(),
|
|
161308
|
+
getViewProperties: () => this.loader.viewProperties(),
|
|
161309
|
+
getTableStyleMap: () => this.loader.tableStyleMap(),
|
|
161310
|
+
getTableStylesDefaultId: () => this.loader.tableStylesDefaultId(),
|
|
161311
|
+
getTagCollections: () => this.loader.tagCollections(),
|
|
159031
161312
|
setCanvasSize: (size) => {
|
|
159032
161313
|
this.loader.canvasSize.set(size);
|
|
159033
161314
|
this.editor.dirty.set(true);
|
|
@@ -159052,6 +161333,22 @@ class PowerPointViewerComponent {
|
|
|
159052
161333
|
this.loader.appProperties.set(props);
|
|
159053
161334
|
this.editor.dirty.set(true);
|
|
159054
161335
|
},
|
|
161336
|
+
setViewProperties: (props) => {
|
|
161337
|
+
this.loader.viewProperties.set(props);
|
|
161338
|
+
this.editor.dirty.set(true);
|
|
161339
|
+
},
|
|
161340
|
+
setTableStyleMap: (map) => {
|
|
161341
|
+
this.loader.tableStyleMap.set(map);
|
|
161342
|
+
this.editor.dirty.set(true);
|
|
161343
|
+
},
|
|
161344
|
+
setTableStylesDefaultId: (id) => {
|
|
161345
|
+
this.loader.tableStylesDefaultId.set(id);
|
|
161346
|
+
this.editor.dirty.set(true);
|
|
161347
|
+
},
|
|
161348
|
+
setTagCollections: (tags) => {
|
|
161349
|
+
this.loader.tagCollections.set([...tags]);
|
|
161350
|
+
this.editor.dirty.set(true);
|
|
161351
|
+
},
|
|
159055
161352
|
// Scope the assistant to the user's AI picks / pinned focus / live
|
|
159056
161353
|
// selection (see AiPanelStore); falls back to the whole active slide.
|
|
159057
161354
|
getFocusedTargets: () => this.aiPanelStore.getFocusedTargets(),
|
|
@@ -159415,6 +161712,29 @@ class PowerPointViewerComponent {
|
|
|
159415
161712
|
applyRemoteSlides: (slides) => this.editor.applyRemoteSlides(slides),
|
|
159416
161713
|
canvasSize: () => this.loader.canvasSize(),
|
|
159417
161714
|
getSourceBytes: () => this.fileIO.sourceBytes(),
|
|
161715
|
+
// Session-level save options (view properties, table styles, tags, deck
|
|
161716
|
+
// properties, ...), built the same way as `loader.saveSlides`, so an
|
|
161717
|
+
// owner's write-back file no longer drops every session-level edit
|
|
161718
|
+
// outside `slides`.
|
|
161719
|
+
getSaveOptions: () => buildDeckSaveOptions({
|
|
161720
|
+
headerFooter: this.loader.headerFooter(),
|
|
161721
|
+
presentationProperties: this.loader.presentationProperties(),
|
|
161722
|
+
viewProperties: this.loader.viewProperties(),
|
|
161723
|
+
customShows: this.loader.customShows(),
|
|
161724
|
+
sections: this.loader.sections(),
|
|
161725
|
+
coreProperties: this.loader.coreProperties(),
|
|
161726
|
+
appProperties: this.loader.appProperties(),
|
|
161727
|
+
customProperties: this.loader.customProperties(),
|
|
161728
|
+
tagCollections: this.loader.tagCollections(),
|
|
161729
|
+
slideMasters: this.loader.slideMasters(),
|
|
161730
|
+
notesMaster: this.loader.notesMaster(),
|
|
161731
|
+
handoutMaster: this.loader.handoutMaster(),
|
|
161732
|
+
slideSize: this.loader.slideSizeSelection().size,
|
|
161733
|
+
tableStyleMap: this.loader.tableStyleMap(),
|
|
161734
|
+
tableStylesDefaultId: this.loader.tableStylesDefaultId(),
|
|
161735
|
+
tableStylesToDelete: this.loader.tableStylesToDelete(),
|
|
161736
|
+
embedFonts: this.loader.embedFonts(),
|
|
161737
|
+
}),
|
|
159418
161738
|
currentSlides: () => this.editor.slides(),
|
|
159419
161739
|
emitStart: (config) => this.startCollaboration.emit(config),
|
|
159420
161740
|
emitStop: () => this.stopCollaboration.emit(),
|
|
@@ -164689,5 +167009,5 @@ function cn(...values) {
|
|
|
164689
167009
|
* Generated bundle index. Do not edit.
|
|
164690
167010
|
*/
|
|
164691
167011
|
|
|
164692
|
-
export { ColorChangedImageComponent as $, AFTER_ANIMATION_VALUES as A, AnimationPanelComponent as B, AnimationPlaybackService as C, AutosaveRecoveryDialogComponent as D, AutosaveService as E, BroadcastDialogComponent as F, CHART_EDITOR_STYLES as G, CURSOR_PALETTE as H, CanvasFitService as I, ChartAxisOptionsComponent as J, ChartAxisStyleOptionsComponent as K, ChartComboTypeOptionsComponent as L, ChartDataEditorComponent as M, ChartDataLabelOptionsComponent as N, ChartDatapointMarkerOptionsComponent as O, ChartDatapointOptionsComponent as P, ChartDisplayOptionsComponent as Q, ChartElementViewComponent as R, ChartErrorBarOptionsComponent as S, ChartMarkerOptionsComponent as T, ChartPartSelectionService as U, ChartPrimitivesComponent as V, ChartRendererComponent as W, ChartTrendlineOptionsComponent as X, ChartTypeSelectorComponent as Y, CollaborationCursorsComponent as Z, CollaborationService as _, ALIGN_OPTIONS as a, InspectorPanelComponent as a$, CommentMarkersOverlayComponent as a0, CommentsPanelComponent as a1, CommentsService as a2, ComparePanelComponent as a3, ConnectorRendererComponent as a4, ConnectorTextOverlayComponent as a5, CustomShowsComponent as a6, DEFAULT_BOUNDS as a7, DEFAULT_BROADCAST_SERVER_URL as a8, DEFAULT_CANVAS_HEIGHT as a9, ElementRendererComponent as aA, EmbeddedFontsService as aB, EncryptedFileDialogComponent as aC, EquationEditorDialogComponent as aD, EquationRendererComponent as aE, EquationTemplateGalleryComponent as aF, ExportProgressModalComponent as aG, ExportService as aH, FieldContextService as aI, FindBarComponent as aJ, FindReplaceBarComponent as aK, FollowModeBarComponent as aL, FontEmbeddingListComponent as aM, FontEmbeddingPanelComponent as aN, GALLERY_THEME_PRESETS as aO, GOOGLE_WEBFONTS_LINK_ID as aP, GRIDLINE_COLOR$1 as aQ, GoogleWebfontsService as aR, GradientPickerComponent as aS, HANDOUT_OPTIONS as aT, HeaderFooterDialogComponent as aU, HyperlinkDialogComponent as aV, ImagePropertiesPanelComponent as aW, InkDrawingService as aX, InkRendererComponent as aY, InsertSmartArtDialogComponent as aZ, InspectorPaneHeaderComponent as a_, DEFAULT_CANVAS_WIDTH as aa, DEFAULT_COLOR_SCHEME as ab, DEFAULT_FILL_COLOR$1 as ac, DEFAULT_LAYOUT as ad, DEFAULT_PALETTE$1 as ae, DEFAULT_PATTERN_FILL_PRESET as af, DEFAULT_PRINT_SETTINGS as ag, DEFAULT_SLIDE_BACKGROUND as ah, DEFAULT_STROKE_COLOR as ai, DEFAULT_STYLE as aj, DEFAULT_TABLE_ROW_HEIGHT as ak, DEFAULT_TEXT_COLOR$2 as al, DEFAULT_VIEWER_PROFILE as am, DIRECTIONAL_PRESETS as an, DIRECTION_OPTIONS as ao, DocumentPropertiesCardComponent as ap, EMBEDDED_FONTS_STYLE_ID as aq, EMPHASIS_PRESETS as ar, ENTRANCE_PRESETS as as, TEMPLATES as at, EXIT_PRESETS as au, EditorContextMenuComponent as av, EditorHistory as aw, EditorStateService as ax, EditorToolbarComponent as ay, EffectsPanelComponent as az, ANIMATION_PRESET_CATEGORIES as b, RibbonComponent as b$, IsMobileService as b0, KeepAnnotationsDialogComponent as b1, LOCALE_CATALOG as b2, LONG_PRESS_DURATION_MS as b3, LONG_PRESS_MOVE_TOLERANCE_PX as b4, LoadContentService as b5, LocalPresencePublisher as b6, MAX_ZOOM_SCALE as b7, MIN_ZOOM_SCALE as b8, MOTION_PATH_COLUMNS as b9, PasswordStrengthMeterComponent as bA, PowerPointViewerComponent as bB, PresentToolbarAutoHide as bC, PresentationAnnotationOverlayComponent as bD, PresentationAnnotationsService as bE, PresentationOverlayComponent as bF, PresentationPropertiesPanelComponent as bG, PresentationSettingsCardComponent as bH, PresentationSubtitleBarComponent as bI, PresentationToolbarComponent as bJ, PresentationTransitionOverlayComponent as bK, PresenterViewComponent as bL, PresenterWindowService as bM, PrintDialogComponent as bN, PrintService as bO, PrintSettingsPanelComponent as bP, PropertiesDialogComponent as bQ, REPEAT_MODE_OPTIONS as bR, RESIZE_HANDLES as bS, RULER_FONT_SIZE as bT, RULER_THICKNESS as bU, ReadingViewOverlayComponent as bV, RemoteSelectionOverlayComponent as bW, RibbonAnimationGalleryComponent as bX, RibbonAnimationsSectionComponent as bY, RibbonArrangeSectionComponent as bZ, RibbonColorPopoverComponent as b_, MediaPreviewComponent as ba, MediaPropertiesPanelComponent as bb, MediaRendererComponent as bc, MediaTrimTimelineComponent as bd, MobileBottomBarComponent as be, MobileMenuSheetComponent as bf, MobilePresenterViewComponent as bg, MobileSheetComponent as bh, MobileSlidesSheetComponent as bi, MobileToolbarComponent as bj, ModalDialogComponent as bk, Model3DRendererComponent as bl, NotesHandoutCardComponent as bm, NotesPanelComponent as bn, NotesToolbarComponent as bo, OleRendererComponent as bp, OutlineViewOverlayComponent as bq, POWER_POINT_VIEWER_PROVIDERS as br, PPTX_OPEN_ACCEPT as bs, PRESENTATION_OPEN_EXTENSIONS as bt, PRESENTER_CHANNEL_NAME as bu, PRESENTER_MSG_ORIGIN as bv, PRESENTER_TIMER_SEGMENT_MS as bw, PX_PER_CM as bx, PX_PER_INCH as by, PasswordProtectionDialogComponent as bz, AUDIENCE_HASH as c, TEXT_3D_TOP_BEVEL_KEYS as c$, RibbonDesignSectionComponent as c0, RibbonDrawSectionComponent as c1, RibbonDrawingGroupComponent as c2, RibbonEditingSectionComponent as c3, RibbonFileSectionComponent as c4, RibbonFontControlsComponent as c5, RibbonHomeSectionComponent as c6, RibbonHyperlinkButtonComponent as c7, RibbonInsertFieldsComponent as c8, RibbonInsertSectionComponent as c9, SettingsLanguageTabComponent as cA, ShareDialogComponent as cB, ShortcutPanelComponent as cC, ShowOptionsFieldsetComponent as cD, ShowSlidesFieldsetComponent as cE, SignatureStrippedDialogComponent as cF, SignaturesPanelComponent as cG, SignaturesService as cH, SlideBackgroundCardComponent as cI, SlideCanvasComponent as cJ, SlideDefaultInspectorComponent as cK, SlideDiffChangesComponent as cL, SlideDiffRowComponent as cM, SlideDiffThumbnailsComponent as cN, SlideSizeCardComponent as cO, SlideSorterOverlayComponent as cP, SlideThemeOverridePanelComponent as cQ, SlideTransitionCardComponent as cR, SlidesPanelComponent as cS, SmartArt3DRendererComponent as cT, SmartArt3DService as cU, SmartArtPreviewComponent as cV, SmartArtPropertiesComponent as cW, SmartArtRendererComponent as cX, StatusBarComponent as cY, TABLE_STRUCTURE_TOGGLES as cZ, TEXT_3D_BOTTOM_BEVEL_KEYS as c_, RibbonMotionPathGalleryComponent as ca, RibbonParagraphControlsComponent as cb, RibbonPrimaryRowComponent as cc, RibbonReviewSectionComponent as cd, RibbonShapeExtrasComponent as ce, RibbonSlideshowSectionComponent as cf, RibbonTransitionsSectionComponent as cg, RibbonViewSectionComponent as ch, RulerGuidesService as ci, SEQUENCE_OPTIONS as cj, SEVERITY_GROUPS as ck, SEVERITY_LABELS as cl, SHORTCUT_REFERENCE_ITEMS as cm, SLIDE_TRANSITION_KEYFRAMES as cn, DEFAULT_PALETTE as co, PALETTES$1 as cp, SMART_ART_COLOR_SCHEMES as cq, SMART_ART_STYLE_OPTIONS as cr, SUB_ITEM_LABEL as cs, SVG_WARP_PRESETS as ct, SWIPE_MAX_VERTICAL_PX as cu, SWIPE_THRESHOLD_PX as cv, SelectionPaneComponent as cw, SetUpSlideShowDialogComponent as cx, SettingsAppearanceTabComponent as cy, SettingsDialogComponent as cz, AUDIENCE_NONCE_KEY as d, animationPresetLabelKey as d$, TEXT_DIRECTION_OPTIONS$1 as d0, THEME_CATALOG as d1, TIMING_CURVE_OPTIONS as d2, TRIGGER_OPTIONS as d3, TYPE_LABELS as d4, TableCellAdvancedFillComponent as d5, TableCellFormattingComponent as d6, TableDataEditorComponent as d7, TablePropertiesComponent as d8, TableRendererComponent as d9, ViewerFileIOService as dA, ViewerFindReplaceService as dB, ViewerFormatPainterService as dC, ViewerInspectorPanelService as dD, ViewerKeyboardService as dE, ViewerMobileSheetService as dF, ViewerPresentationModeService as dG, ViewerThemeGalleryService as dH, ViewerTouchGesturesService as dI, ViewerZoomService as dJ, WEBM_MIME_CANDIDATES as dK, WriteBackScheduler as dL, ZERO_LINE_COLOR as dM, ZoomNavigationService as dN, ZoomRendererComponent as dO, ZoomTargetService as dP, addCategory as dQ, addCommentToList as dR, addGradientStopPatch as dS, addItem as dT, addSeries as dU, addSubItem as dV, advanceStep as dW, affordanceElements as dX, aiToggleVisible as dY, alignPatch as dZ, animationFor as d_, TableResizeOverlayComponent as da, TableSelectionService as db, TagsCardComponent as dc, Text3DBevelSectionComponent as dd, Text3DPanelComponent as de, TextAdvancedPanelComponent as df, ThemeEditorFieldsComponent as dg, ThemeGalleryComponent as dh, ThemeSelectorCardComponent as di, TitleBarComponent as dj, TitleBarSearchComponent as dk, TransitionDirectionPickerComponent as dl, TransitionPreviewComponent as dm, VALIGN_OPTIONS as dn, VIEWER_THEME as dp, VersionHistoryPanelComponent as dq, ViewerCanvasEditingService as dr, ViewerCollabCursorService as ds, ViewerCollaborationSessionService as dt, ViewerCompareService as du, ViewerCustomShowsService as dv, ViewerDialogsService as dw, ViewerDocumentPropertiesService as dx, ViewerExportService as dy, ViewerExtraDialogsComponent as dz, AVATAR_COLOR_SWATCHES as e, buildTreemapViewModel as e$, annotationMapToInkInserts as e0, applyAcceptedDiff as e1, applyAnimationPreset as e2, applyFindReplacements as e3, applyFormatToElement as e4, applyMove as e5, applyResize as e6, asMediaElement as e7, assignUserColor as e8, attachShowVisibilityPause as e9, buildEquationSegment as eA, buildFallbackViewModel as eB, buildFontFaceRule as eC, buildGradientFillCss as eD, buildGridlinesAndLabels as eE, buildHyperlinkPatch as eF, buildInkContainerStyle as eG, buildInkStrokes as eH, buildLegend as eI, buildMarkTooltip as eJ, buildModel3DContainerStyle as eK, buildModel3DViewModel as eL, buildOleActionModel as eM, buildOleInfoRows as eN, buildPatternFillCss as eO, buildPieViewModel as eP, buildPrintHtmlDocument as eQ, buildPropertiesPatch as eR, buildRadarViewModel as eS, buildRegionMapViewModel as eT, buildSaveSlides as eU, buildShareUrl as eV, buildSmartArtInsertElement as eW, buildSmartArtNodes as eX, buildStockViewModel as eY, buildSurfaceViewModel as eZ, buildTableViewModel as e_, attachTouchGestures as ea, axisTickValues as eb, beginNodeEdit as ec, bevelSizePatch as ed, boolFromEvent as ee, bringForward as ef, bringToFront as eg, buildBarActions as eh, buildBroadcastConfig as ei, buildBroadcastViewerUrl as ej, buildCategoryLabels as ek, buildCellParagraphs as el, buildChartViewModel as em, buildChatLogExport as en, buildChatLogMarkdown as eo, buildChromeStyle as ep, buildClearHyperlinkPatch as eq, buildClickGroups as er, buildColStyles as es, buildCollaborationConfig as et, buildComboViewModel as eu, buildCssGradientFromShapeStyle as ev, buildDuotoneFilter as ew, buildDuotoneFilterId as ex, buildEmbeddedFontStyles as ey, buildEquationElement as ez, AXIS_LABEL_COLOR as f, computeResizeHandleBoxes as f$, buildTrimFragment as f0, buildWaterfallViewModel as f1, buildZeroLine as f2, buildZoomContainerStyle as f3, buildZoomViewModel as f4, bulletIndentPx as f5, canAddTopLevelNode as f6, canEditSmartArtNodes as f7, canGroupSelection as f8, canRemoveTopLevelNode as f9, collectStoredChats as fA, collectUsedFontFamilies as fB, columnWidthStyle as fC, commitNodeText as fD, computeAlign as fE, computeAxisTitlePrimitives as fF, computeBarRects as fG, computeBubbleRadius as fH, computeCornerHandle as fI, computeDistribute as fJ, computeDrawingViewBox as fK, computeErrorBarPrimitives as fL, computeFocusTargets as fM, computeGridSpacingPx as fN, computeHandleBoxes as fO, computeHandoutLayout as fP, computeIsMobile as fQ, computeIsTablet as fR, computeLinePoints as fS, computeLinearRegression as fT, computePageCount as fU, computePieLayout as fV, computePieSlicePath as fW, computePieSlices as fX, computePlotLayout as fY, computeRSquared as fZ, computeRadarPoints as f_, canSetStrokeWidth as fa, canStartBroadcast as fb, canStartShare as fc, canUngroupSelection as fd, canUseClipboard as fe, captionDisplayText as ff, cellRunStyle as fg, cellStyleToStyleMap as fh, cellTdStyle as fi, changeCountLabel as fj, changeIcon as fk, characterSpacingPatch as fl, chartPreserveAspectRatio as fm, checkFontAvailable as fn, clampCursorPosition as fo, clampGifDimensions as fp, clampIndex as fq, clampNotesFontSize as fr, clampScale as fs, clampStep as ft, clearAllLocalViewerData as fu, clearAudienceContent as fv, cn as fw, collectAccessibilityIssues as fx, collectElementText as fy, collectSlideText as fz, AccessibilityPanelComponent as g, forgetSessionDeck as g$, computeRotateHandleBox as g0, computeScatterDots as g1, computeScatterXDomain as g2, computeSelectionBoxes as g3, computeSingleSelected as g4, computeSlideIndices as g5, computeSnap as g6, computeStackedBarRects as g7, computeStackedValueRange as g8, computeTrendlinePrimitives as g9, disableReflectionPatch as gA, disableSoftEdgePatch as gB, duplicateElementById as gC, durationOf as gD, effectsStateOf as gE, enableGlowPatch as gF, enableInnerShadowPatch as gG, enableOuterShadowPatch as gH, enableReflectionPatch as gI, enableSoftEdgePatch as gJ, encodeGif as gK, endShowMediaCleanup as gL, estimatePageCount as gM, exitPresentationFullscreen as gN, exportAiChatLogs as gO, extractPathPoints as gP, eyedropperAvailable as gQ, fillColorOf$1 as gR, findInSlides as gS, findOwningSlideIndex as gT, findSlideIndexByElementId as gU, firstVisibleIndex as gV, fitPolynomial as gW, fitZoom as gX, focusTargetChips as gY, fontMimeForFormat as gZ, fontSizeOf as g_, computeValueRange as ga, convertOmmlToMathMl as gb, copyFormatFromElement as gc, countAccessibilityIssues as gd, countAnnotationStrokes as ge, createAngularAiBridge as gf, createCustomShow as gg, createSwipeDismissDrag as gh, createWebrtcBundle as gi, createWebsocketBundle as gj, cssObjectToStyleMap as gk, currentColorScheme as gl, currentLayout as gm, currentStyle as gn, defaultCssVars as go, defaultRadius as gp, defaultThemeColors as gq, deleteElementsByIds as gr, deleteVersion as gs, demoteNode as gt, deriveModel3DBlobUrl as gu, derivePresenceList as gv, describeSmartArtBounds as gw, disableGlowPatch as gx, disableInnerShadowPatch as gy, disableOuterShadowPatch as gz, AccessibilityService as h, isBrowserOpenableMime as h$, formatAxisValue as h0, formatBytes as h1, formatCursorLabel as h2, formatElapsed as h3, formatFileSize as h4, formatPropertyDate as h5, formatTime as h6, fpsToFrameIntervalMs as h7, generateBroadcastRoomId as h8, generateCommentId as h9, getSpeechRecognitionCtor as hA, getTextBlockStyle as hB, getTextWarp as hC, getTouchDistance as hD, getWarpCategory as hE, getWarpPath as hF, gradientStateFromStyle as hG, gradientStateOf as hH, gradientStatePatch as hI, gradientStopColorCommitPatch as hJ, gridColumns as hK, groupIssuesBySeverity as hL, hasAnimation as hM, hasCopyableFormat as hN, hasExistingLink as hO, hasExitedFullscreen as hP, hasGradientFill as hQ, hasPressureVariation as hR, hasVisibleSlideAfter as hS, headerLabel as hT, imageDimensions as hU, inkViewBox as hV, insertTableElementColumn as hW, insertTableElementRow as hX, interpolateWidth as hY, isAudienceTab as hZ, isBold as h_, generateCustomShowId as ha, generatePressureCircles as hb, generateTicks as hc, getClrChangeParams as hd, getContainerStyle as he, getDuotoneFilterDef as hf, getEffectSoundState as hg, getImageSrc as hh, getLocalStorageUsageSummary as hi, getOleAriaLabel as hj, getOleBadgeLabel as hk, getOleDisplayName as hl, getOleDownloadFileName as hm, getOleTypeColor as hn, getOleTypeLabel as ho, getPasswordStrength as hp, getPatternSvg as hq, getPlaceholderStyle as hr, getVersions as hs, getResolvedShapeClipPath as ht, getResolvedShapeClipPathFor as hu, getSessionTabId as hv, getShapeFillStrokeStyle as hw, getSlideBackgroundStyle as hx, getSlideTransitionAnimations as hy, getSmartArtNodeBounds as hz, AccountPageComponent as i, ooxmlDashToCssBorderStyle as i$, isChildNode as i0, isElementInteractive as i1, isInjectableUrl as i2, isItalic as i3, isLegacyBinaryPresentation as i4, isPpactionUrl as i5, isPresenterMessage as i6, isSigned as i7, isSupportedPresentationFile as i8, isTextElement as i9, moveElementBy as iA, moveNodeDown as iB, moveNodeUp as iC, msToFrameDelayCs as iD, narrowToCircle as iE, narrowToPolygon as iF, narrowToRect as iG, newChartElement as iH, newEquationElement as iI, newPresetShapeElement as iJ, newShapeElement as iK, newSmartArtElement as iL, newTableElement as iM, newTextElement as iN, nextVisibleIndex as iO, nodeBold as iP, nodeEditBox as iQ, nodeFillColor as iR, nodeFontColor as iS, nodeIdFromKey as iT, nodeItalic as iU, nodeStyle as iV, normalizeFontFormat as iW, normalizeSlidesPerPage as iX, normalizeValue as iY, numFromEvent as iZ, ommlToMathml as i_, isTwoTableFocus as ia, isUnderline as ib, isUrlSafe as ic, isValidRoomId as id, isViewportBackgroundPressTarget as ie, isZoomActivationKey as ig, issueTrackKey as ih, issueTypeLabel as ii, keyToLabel as ij, lastVisibleIndex as ik, latexToMathml as il, layoutConnectorPaints as im, layoutNodeLabels as io, linePointsToSvgString as ip, lineSpacingPatch as iq, loadAudienceContent as ir, loadSessionDeck as is, mediaFallbackFor as it, mediaSurfaceFor as iu, mergeCaptionResults as iv, mergeDown as iw, mergeRight as ix, mergeSelection as iy, mergeTablesDirective as iz, ActionSettingsPanelComponent as j, resolveSlideAutoAdvanceMs as j$, openNativeEyeDropper as j0, overallStatus as j1, paletteColor as j2, parseAudienceNonce as j3, parseNodeTextarea as j4, partitionSlides as j5, patchChartData as j6, patchChartStyle as j7, patchTableData as j8, patchTextStyle as j9, removeCategory as jA, removeTableElementColumn as jB, removeCommentFromList as jC, removeElementAnimation as jD, removeGradientStopPatch as jE, removeNode as jF, removeTableElementRow as jG, removeSeries as jH, renderToCanvas as jI, reorderAnimationDown as jJ, reorderAnimationUp as jK, replaceInSlides as jL, replaceMatch as jM, requestPresentationFullscreen as jN, resizeElement as jO, resolveCaptionTracks as jP, resolveChartKind as jQ, resolveFontVariant as jR, resolveHyperlinkHref as jS, resolveInteractiveElementId as jT, resolveMediaSrc as jU, resolveOleType as jV, resolveParagraphBullet as jW, resolvePresenterNotes as jX, resolveProfileInitial as jY, resolveRegionCode as jZ, resolveRibbonCanGroup as j_, patternPresetOptions as ja, pendingElementStyles as jb, pickColorByClickFallback as jc, pickFile as jd, pickSupportedMimeType as je, planGifFrames as jf, planVideoSegments as jg, pointsToSvgPathD as jh, presenceToCursors as ji, presentationBaseName as jj, presentationStageStyle as jk, presenterTimerProgress as jl, presetByLayout as jm, presetsForCategory as jn, pressuresToWidths as jo, prevVisibleIndex as jp, projectDrawingShapes as jq, promoteNode as jr, provideViewerTheme as js, radarAngle as jt, radarRingPoints as ju, readAsDataUrl as jv, recordWebm as jw, registerCrossSlideAudio as jx, rememberSessionDeck as jy, removeAnimation as jz, AdvancedChartEditorComponent as k, setSeriesTrendline as k$, resolvePalette as k0, resolveThemeCatalogEntry as k1, resolveTransitionDuration as k2, restoreSessionDeck as k3, revealedElementStyles as k4, routeOrthogonalConnector as k5, rowStyle as k6, rulerDragToGuidePosition as k7, rulerHighlight as k8, rulerStripTicks as k9, setAxisTitleStyle as kA, setCategoryLabel as kB, setCellText as kC, setColorScheme as kD, setDataLabels as kE, setDataPointExplosion as kF, setDataPointFill as kG, setDataPointLabel as kH, setDataPointMarker as kI, setDelay as kJ, setDirection as kK, setDuration as kL, setEffectSound as kM, setElementPosition as kN, setGridlineStyle as kO, setLayout as kP, setLegend as kQ, setNodeStyle as kR, setNodeText as kS, setRepeatCount as kT, setRepeatMode as kU, setSequence as kV, setSeriesChartType as kW, setSeriesColor as kX, setSeriesErrorBars as kY, setSeriesMarker as kZ, setSeriesName as k_, sampleColorFromSlide as ka, sanitizeColor as kb, sanitizeSlideIndex as kc, sanitizeUserName as kd, saveViewerProfile as ke, savedPresentationFileName as kf, scanAvailableFonts as kg, searchSlides as kh, seedBroadcastFields as ki, seedHyperlinkDraft as kj, seedPropertiesDraft as kk, seedShareFields as kl, segmentFrameCount as km, selectValue$3 as kn, sendBackward as ko, sendToBack as kp, sequentialColorScale as kq, serializeWriteBack as kr, seriesColor as ks, setAfterAnimation as kt, setAfterAnimationColor as ku, setAnimationEmphasis as kv, setAnimationEntrance as kw, setAnimationExit as kx, setAxis as ky, setAxisLogScale as kz, AiChangeOverlayComponent as l, vermilionDarkColors as l$, setSeriesValue as l0, setStyle as l1, setTimingCurve as l2, setTitle as l3, setTrigger as l4, setTriggerShapeId as l5, shapeStylePatch$1 as l6, sheetAfterNavigate as l7, shouldBlockClickAdvance as l8, shouldUseSvgWarp as l9, textColorOf as lA, textDirectionPatch as lB, textFontSizePatch as lC, textStyleOf as lD, textStylePatch as lE, themeStyle as lF, themeToCssVars as lG, thumbnailHeight as lH, thumbnailZoom as lI, toggleCommentResolvedInList as lJ, toggleNodeBold as lK, toggleNodeItalic as lL, toggleSheet as lM, topLevelNodeCount as lN, transformSelectedTextCase as lO, translationsEn as lP, updateElementById as lQ, updateGlowPatch as lR, updateGradientStopPatch as lS, updateInnerShadowPatch as lT, updateOuterShadowPatch as lU, updateReflectionPatch as lV, vAlignPatch as lW, validatePassword as lX, validatePrintSettings as lY, validateRoomId as lZ, valueToY as l_, showDirectionPicker as la, showsTemplateAffordance as lb, signatureCountLabel as lc, signatureKey as ld, signatureTimestamp as le, signerName as lf, statusLabel as lg, slideNumberOf as lh, slidesWithReappliedLayout as li, smartArtNodes as lj, paletteColour as lk, snapToGridStep as ll, splitCursorCell as lm, splitMergedCell as ln, statusKind as lo, statusLabel$1 as lp, storeAudienceContent as lq, stringFromEvent$5 as lr, strokeColorOf as ls, strokeToInkElement as lt, strokeWidthOf as lu, styleShadowFilter as lv, surfaceColor as lw, textAdvancedPatch as lx, textAdvancedStateFromStyle as ly, textAdvancedStateOf as lz, AiChatPanelComponent as m, vermilionDarkTheme as m0, vermilionLightColors as m1, vermilionLightTheme as m2, vermilionRadius as m3, waypointsToPathD as m4, withManualLayouts as m5, worstStatus as m6, zoomTargetSlideIndex as m7, AiChatService as n, AiComposerComponent as o, AiFocusBarComponent as p, AiFocusHighlightOverlayComponent as q, AiHistoryMenuComponent as r, AiHistoryService as s, toChatSummary as t, AiMessageListComponent as u, AiPanelStore as v, AiProposalCardComponent as w, AiSettingsSectionComponent as x, AiToolCallCardComponent as y, AnimationAuthorPanelComponent as z };
|
|
164693
|
-
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-
|
|
167012
|
+
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, InspectorPaneHeaderComponent 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, EffectsPanelComponent as aA, ElementRendererComponent as aB, EmbeddedFontsService as aC, EncryptedFileDialogComponent as aD, EquationEditorDialogComponent as aE, EquationRendererComponent as aF, EquationTemplateGalleryComponent as aG, ExportProgressModalComponent as aH, ExportService as aI, FieldContextService as aJ, FindBarComponent as aK, FindReplaceBarComponent as aL, FollowModeBarComponent as aM, FontEmbeddingListComponent as aN, FontEmbeddingPanelComponent as aO, GALLERY_THEME_PRESETS as aP, GOOGLE_WEBFONTS_LINK_ID as aQ, GRIDLINE_COLOR$1 as aR, GoogleWebfontsService as aS, GradientPickerComponent as aT, HANDOUT_OPTIONS as aU, HeaderFooterDialogComponent as aV, HyperlinkDialogComponent as aW, ImagePropertiesPanelComponent as aX, InkDrawingService as aY, InkRendererComponent as aZ, InsertSmartArtDialogComponent 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, EMBEDDED_FONTS_STYLE_ID as ar, EMPHASIS_PRESETS as as, ENTRANCE_PRESETS as at, TEMPLATES as au, EXIT_PRESETS as av, EditorContextMenuComponent as aw, EditorHistory as ax, EditorStateService as ay, EditorToolbarComponent as az, ANIMATION_PRESET_CATEGORIES as b, RibbonColorPopoverComponent as b$, InspectorPanelComponent as b0, IsMobileService as b1, KeepAnnotationsDialogComponent as b2, LOCALE_CATALOG as b3, LONG_PRESS_DURATION_MS as b4, LONG_PRESS_MOVE_TOLERANCE_PX as b5, LoadContentService as b6, LocalPresencePublisher as b7, MAX_ZOOM_SCALE as b8, MIN_ZOOM_SCALE as b9, PasswordProtectionDialogComponent as bA, PasswordStrengthMeterComponent as bB, PowerPointViewerComponent as bC, PresentToolbarAutoHide as bD, PresentationAnnotationOverlayComponent as bE, PresentationAnnotationsService as bF, PresentationOverlayComponent as bG, PresentationPropertiesPanelComponent as bH, PresentationSettingsCardComponent as bI, PresentationSubtitleBarComponent as bJ, PresentationToolbarComponent as bK, PresentationTransitionOverlayComponent as bL, PresenterViewComponent as bM, PresenterWindowService as bN, PrintDialogComponent as bO, PrintService as bP, PrintSettingsPanelComponent as bQ, PropertiesDialogComponent as bR, REPEAT_MODE_OPTIONS as bS, RESIZE_HANDLES as bT, RULER_FONT_SIZE as bU, RULER_THICKNESS as bV, ReadingViewOverlayComponent as bW, RemoteSelectionOverlayComponent as bX, RibbonAnimationGalleryComponent as bY, RibbonAnimationsSectionComponent as bZ, RibbonArrangeSectionComponent as b_, MOTION_PATH_COLUMNS as ba, MediaPreviewComponent as bb, MediaPropertiesPanelComponent as bc, MediaRendererComponent as bd, MediaTrimTimelineComponent as be, MobileBottomBarComponent as bf, MobileMenuSheetComponent as bg, MobilePresenterViewComponent as bh, MobileSheetComponent as bi, MobileSlidesSheetComponent as bj, MobileToolbarComponent as bk, ModalDialogComponent as bl, Model3DRendererComponent as bm, NotesHandoutCardComponent as bn, NotesPanelComponent as bo, NotesToolbarComponent as bp, OleRendererComponent as bq, OutlineViewOverlayComponent as br, POWER_POINT_VIEWER_PROVIDERS as bs, PPTX_OPEN_ACCEPT as bt, PRESENTATION_OPEN_EXTENSIONS as bu, PRESENTER_CHANNEL_NAME as bv, PRESENTER_MSG_ORIGIN as bw, PRESENTER_TIMER_SEGMENT_MS as bx, PX_PER_CM as by, PX_PER_INCH as bz, AUDIENCE_HASH as c, TEXT_3D_BOTTOM_BEVEL_KEYS as c$, RibbonComponent as c0, RibbonDesignSectionComponent as c1, RibbonDrawSectionComponent as c2, RibbonDrawingGroupComponent as c3, RibbonEditingSectionComponent as c4, RibbonFileSectionComponent as c5, RibbonFontControlsComponent as c6, RibbonHomeSectionComponent as c7, RibbonHyperlinkButtonComponent as c8, RibbonInsertFieldsComponent as c9, SettingsDialogComponent as cA, SettingsLanguageTabComponent as cB, ShareDialogComponent as cC, ShortcutPanelComponent as cD, ShowOptionsFieldsetComponent as cE, ShowSlidesFieldsetComponent as cF, SignatureStrippedDialogComponent as cG, SignaturesPanelComponent as cH, SignaturesService as cI, SlideBackgroundCardComponent as cJ, SlideCanvasComponent as cK, SlideDefaultInspectorComponent as cL, SlideDiffChangesComponent as cM, SlideDiffRowComponent as cN, SlideDiffThumbnailsComponent as cO, SlideSizeCardComponent as cP, SlideSorterOverlayComponent as cQ, SlideThemeOverridePanelComponent as cR, SlideTransitionCardComponent as cS, SlidesPanelComponent as cT, SmartArt3DRendererComponent as cU, SmartArt3DService as cV, SmartArtPreviewComponent as cW, SmartArtPropertiesComponent as cX, SmartArtRendererComponent as cY, StatusBarComponent as cZ, TABLE_STRUCTURE_TOGGLES as c_, RibbonInsertSectionComponent as ca, RibbonMotionPathGalleryComponent as cb, RibbonParagraphControlsComponent as cc, RibbonPrimaryRowComponent as cd, RibbonReviewSectionComponent as ce, RibbonShapeExtrasComponent as cf, RibbonSlideshowSectionComponent as cg, RibbonTransitionsSectionComponent as ch, RibbonViewSectionComponent as ci, RulerGuidesService as cj, SEQUENCE_OPTIONS as ck, SEVERITY_GROUPS as cl, SEVERITY_LABELS as cm, SHORTCUT_REFERENCE_ITEMS as cn, SLIDE_TRANSITION_KEYFRAMES as co, DEFAULT_PALETTE as cp, PALETTES$1 as cq, SMART_ART_COLOR_SCHEMES as cr, SMART_ART_STYLE_OPTIONS as cs, SUB_ITEM_LABEL as ct, SVG_WARP_PRESETS as cu, SWIPE_MAX_VERTICAL_PX as cv, SWIPE_THRESHOLD_PX as cw, SelectionPaneComponent as cx, SetUpSlideShowDialogComponent as cy, SettingsAppearanceTabComponent as cz, AUDIENCE_NONCE_KEY as d, animationFor as d$, TEXT_3D_TOP_BEVEL_KEYS as d0, TEXT_DIRECTION_OPTIONS$1 as d1, THEME_CATALOG as d2, TIMING_CURVE_OPTIONS as d3, TRIGGER_OPTIONS as d4, TYPE_LABELS as d5, TableCellAdvancedFillComponent as d6, TableCellFormattingComponent as d7, TableDataEditorComponent as d8, TablePropertiesComponent as d9, ViewerExtraDialogsComponent as dA, ViewerFileIOService as dB, ViewerFindReplaceService as dC, ViewerFormatPainterService as dD, ViewerInspectorPanelService as dE, ViewerKeyboardService as dF, ViewerMobileSheetService as dG, ViewerPresentationModeService as dH, ViewerThemeGalleryService as dI, ViewerTouchGesturesService as dJ, ViewerZoomService as dK, WEBM_MIME_CANDIDATES as dL, WriteBackScheduler as dM, ZERO_LINE_COLOR as dN, ZoomNavigationService as dO, ZoomRendererComponent as dP, ZoomTargetService as dQ, addCategory as dR, addCommentToList as dS, addGradientStopPatch as dT, addItem as dU, addSeries as dV, addSubItem as dW, advanceStep as dX, affordanceElements as dY, aiToggleVisible as dZ, alignPatch as d_, TableRendererComponent as da, TableResizeOverlayComponent as db, TableSelectionService as dc, TagsCardComponent as dd, Text3DBevelSectionComponent as de, Text3DPanelComponent as df, TextAdvancedPanelComponent as dg, ThemeEditorFieldsComponent as dh, ThemeGalleryComponent as di, ThemeSelectorCardComponent as dj, TitleBarComponent as dk, TitleBarSearchComponent as dl, TransitionDirectionPickerComponent as dm, TransitionPreviewComponent as dn, VALIGN_OPTIONS as dp, VIEWER_THEME as dq, VersionHistoryPanelComponent as dr, ViewerCanvasEditingService as ds, ViewerCollabCursorService as dt, ViewerCollaborationSessionService as du, ViewerCompareService as dv, ViewerCustomShowsService as dw, ViewerDialogsService as dx, ViewerDocumentPropertiesService as dy, ViewerExportService as dz, AVATAR_COLOR_SWATCHES as e, buildTableViewModel as e$, animationPresetLabelKey as e0, annotationMapToInkInserts as e1, applyAcceptedDiff as e2, applyAnimationPreset as e3, applyFindReplacements as e4, applyFormatToElement as e5, applyMove as e6, applyResize as e7, asMediaElement as e8, assignUserColor as e9, buildEquationElement as eA, buildEquationSegment as eB, buildFallbackViewModel as eC, buildFontFaceRule as eD, buildGradientFillCss as eE, buildGridlinesAndLabels as eF, buildHyperlinkPatch as eG, buildInkContainerStyle as eH, buildInkStrokes as eI, buildLegend as eJ, buildMarkTooltip as eK, buildModel3DContainerStyle as eL, buildModel3DViewModel as eM, buildOleActionModel as eN, buildOleInfoRows as eO, buildPatternFillCss as eP, buildPieViewModel as eQ, buildPrintHtmlDocument as eR, buildPropertiesPatch as eS, buildRadarViewModel as eT, buildRegionMapViewModel as eU, buildSaveSlides as eV, buildShareUrl as eW, buildSmartArtInsertElement as eX, buildSmartArtNodes as eY, buildStockViewModel as eZ, buildSurfaceViewModel as e_, attachShowVisibilityPause as ea, attachTouchGestures as eb, axisTickValues as ec, beginNodeEdit as ed, bevelSizePatch as ee, boolFromEvent as ef, bringForward as eg, bringToFront as eh, buildBarActions as ei, buildBroadcastConfig as ej, buildBroadcastViewerUrl as ek, buildCategoryLabels as el, buildCellParagraphs as em, buildChartViewModel as en, buildChatLogExport as eo, buildChatLogMarkdown as ep, buildChromeStyle as eq, buildClearHyperlinkPatch as er, buildClickGroups as es, buildColStyles as et, buildCollaborationConfig as eu, buildComboViewModel as ev, buildCssGradientFromShapeStyle as ew, buildDuotoneFilter as ex, buildDuotoneFilterId as ey, buildEmbeddedFontStyles as ez, AXIS_LABEL_COLOR as f, computeRadarPoints as f$, buildTreemapViewModel as f0, buildTrimFragment as f1, buildWaterfallViewModel as f2, buildZeroLine as f3, buildZoomContainerStyle as f4, buildZoomViewModel as f5, bulletIndentPx as f6, canAddTopLevelNode as f7, canEditSmartArtNodes as f8, canGroupSelection as f9, collectSlideText as fA, collectStoredChats as fB, collectUsedFontFamilies as fC, columnWidthStyle as fD, commitNodeText as fE, computeAlign as fF, computeAxisTitlePrimitives as fG, computeBarRects as fH, computeBubbleRadius as fI, computeCornerHandle as fJ, computeDistribute as fK, computeDrawingViewBox as fL, computeErrorBarPrimitives as fM, computeFocusTargets as fN, computeGridSpacingPx as fO, computeHandleBoxes as fP, computeHandoutLayout as fQ, computeIsMobile as fR, computeIsTablet as fS, computeLinePoints as fT, computeLinearRegression as fU, computePageCount as fV, computePieLayout as fW, computePieSlicePath as fX, computePieSlices as fY, computePlotLayout as fZ, computeRSquared as f_, canRemoveTopLevelNode as fa, canSetStrokeWidth as fb, canStartBroadcast as fc, canStartShare as fd, canUngroupSelection as fe, canUseClipboard as ff, captionDisplayText as fg, cellRunStyle as fh, cellStyleToStyleMap as fi, cellTdStyle as fj, changeCountLabel as fk, changeIcon as fl, characterSpacingPatch as fm, chartPreserveAspectRatio as fn, checkFontAvailable as fo, clampCursorPosition as fp, clampGifDimensions as fq, clampIndex as fr, clampNotesFontSize as fs, clampScale as ft, clampStep as fu, clearAllLocalViewerData as fv, clearAudienceContent as fw, cn as fx, collectAccessibilityIssues as fy, collectElementText as fz, AccessibilityPanelComponent as g, fontSizeOf as g$, computeResizeHandleBoxes as g0, computeRotateHandleBox as g1, computeScatterDots as g2, computeScatterXDomain as g3, computeSelectionBoxes as g4, computeSingleSelected as g5, computeSlideIndices as g6, computeSnap as g7, computeStackedBarRects as g8, computeStackedValueRange as g9, disableOuterShadowPatch as gA, disableReflectionPatch as gB, disableSoftEdgePatch as gC, duplicateElementById as gD, durationOf as gE, effectsStateOf as gF, enableGlowPatch as gG, enableInnerShadowPatch as gH, enableOuterShadowPatch as gI, enableReflectionPatch as gJ, enableSoftEdgePatch as gK, encodeGif as gL, endShowMediaCleanup as gM, estimatePageCount as gN, exitPresentationFullscreen as gO, exportAiChatLogs as gP, extractPathPoints as gQ, eyedropperAvailable as gR, fillColorOf$1 as gS, findInSlides as gT, findOwningSlideIndex as gU, findSlideIndexByElementId as gV, firstVisibleIndex as gW, fitPolynomial as gX, fitZoom as gY, focusTargetChips as gZ, fontMimeForFormat as g_, computeTrendlinePrimitives as ga, computeValueRange as gb, convertOmmlToMathMl as gc, copyFormatFromElement as gd, countAccessibilityIssues as ge, countAnnotationStrokes as gf, createAngularAiBridge as gg, createCustomShow as gh, createSwipeDismissDrag as gi, createWebrtcBundle as gj, createWebsocketBundle as gk, cssObjectToStyleMap as gl, currentColorScheme as gm, currentLayout as gn, currentStyle as go, defaultCssVars as gp, defaultRadius as gq, defaultThemeColors as gr, deleteElementsByIds as gs, deleteVersion as gt, demoteNode as gu, deriveModel3DBlobUrl as gv, derivePresenceList as gw, describeSmartArtBounds as gx, disableGlowPatch as gy, disableInnerShadowPatch as gz, AccessibilityService as h, isBold as h$, forgetSessionDeck as h0, formatAxisValue as h1, formatBytes as h2, formatCursorLabel as h3, formatElapsed as h4, formatFileSize as h5, formatPropertyDate as h6, formatTime as h7, fpsToFrameIntervalMs as h8, generateBroadcastRoomId as h9, getSmartArtNodeBounds as hA, getSpeechRecognitionCtor as hB, getTextBlockStyle as hC, getTextWarp as hD, getTouchDistance as hE, getWarpCategory as hF, getWarpPath as hG, gradientStateFromStyle as hH, gradientStateOf as hI, gradientStatePatch as hJ, gradientStopColorCommitPatch as hK, gridColumns as hL, groupIssuesBySeverity as hM, hasAnimation as hN, hasCopyableFormat as hO, hasExistingLink as hP, hasExitedFullscreen as hQ, hasGradientFill as hR, hasPressureVariation as hS, hasVisibleSlideAfter as hT, headerLabel as hU, imageDimensions as hV, inkViewBox as hW, insertTableElementColumn as hX, insertTableElementRow as hY, interpolateWidth as hZ, isAudienceTab as h_, generateCommentId as ha, generateCustomShowId as hb, generatePressureCircles as hc, generateTicks as hd, getClrChangeParams as he, getContainerStyle as hf, getDuotoneFilterDef as hg, getEffectSoundState as hh, getImageSrc as hi, getLocalStorageUsageSummary as hj, getOleAriaLabel as hk, getOleBadgeLabel as hl, getOleDisplayName as hm, getOleDownloadFileName as hn, getOleTypeColor as ho, getOleTypeLabel as hp, getPasswordStrength as hq, getPatternSvg as hr, getPlaceholderStyle as hs, getVersions as ht, getResolvedShapeClipPath as hu, getResolvedShapeClipPathFor as hv, getSessionTabId as hw, getShapeFillStrokeStyle as hx, getSlideBackgroundStyle as hy, getSlideTransitionAnimations as hz, AccessibilityTextPanelComponent as i, ommlToMathml as i$, isBrowserOpenableMime as i0, isChildNode as i1, isElementInteractive as i2, isInjectableUrl as i3, isItalic as i4, isLegacyBinaryPresentation as i5, isPpactionUrl as i6, isPresenterMessage as i7, isSigned as i8, isSupportedPresentationFile as i9, mergeTablesDirective as iA, moveElementBy as iB, moveNodeDown as iC, moveNodeUp as iD, msToFrameDelayCs as iE, narrowToCircle as iF, narrowToPolygon as iG, narrowToRect as iH, newChartElement as iI, newEquationElement as iJ, newPresetShapeElement as iK, newShapeElement as iL, newSmartArtElement as iM, newTableElement as iN, newTextElement as iO, nextVisibleIndex as iP, nodeBold as iQ, nodeEditBox as iR, nodeFillColor as iS, nodeFontColor as iT, nodeIdFromKey as iU, nodeItalic as iV, nodeStyle as iW, normalizeFontFormat as iX, normalizeSlidesPerPage as iY, normalizeValue as iZ, numFromEvent as i_, isTextElement as ia, isTwoTableFocus as ib, isUnderline as ic, isUrlSafe as id, isValidRoomId as ie, isViewportBackgroundPressTarget as ig, isZoomActivationKey as ih, issueTrackKey as ii, issueTypeLabel as ij, keyToLabel as ik, lastVisibleIndex as il, latexToMathml as im, layoutConnectorPaints as io, layoutNodeLabels as ip, linePointsToSvgString as iq, lineSpacingPatch as ir, loadAudienceContent as is, loadSessionDeck as it, mediaFallbackFor as iu, mediaSurfaceFor as iv, mergeCaptionResults as iw, mergeDown as ix, mergeRight as iy, mergeSelection as iz, AccountPageComponent as j, resolveRibbonCanGroup as j$, ooxmlDashToCssBorderStyle as j0, openNativeEyeDropper as j1, overallStatus as j2, paletteColor as j3, parseAudienceNonce as j4, parseNodeTextarea as j5, partitionSlides as j6, patchChartData as j7, patchChartStyle as j8, patchTableData as j9, removeAnimation as jA, removeCategory as jB, removeTableElementColumn as jC, removeCommentFromList as jD, removeElementAnimation as jE, removeGradientStopPatch as jF, removeNode as jG, removeTableElementRow as jH, removeSeries as jI, renderToCanvas as jJ, reorderAnimationDown as jK, reorderAnimationUp as jL, replaceInSlides as jM, replaceMatch as jN, requestPresentationFullscreen as jO, resizeElement as jP, resolveCaptionTracks as jQ, resolveChartKind as jR, resolveFontVariant as jS, resolveHyperlinkHref as jT, resolveInteractiveElementId as jU, resolveMediaSrc as jV, resolveOleType as jW, resolveParagraphBullet as jX, resolvePresenterNotes as jY, resolveProfileInitial as jZ, resolveRegionCode as j_, patchTextStyle as ja, patternPresetOptions as jb, pendingElementStyles as jc, pickColorByClickFallback as jd, pickFile as je, pickSupportedMimeType as jf, planGifFrames as jg, planVideoSegments as jh, pointsToSvgPathD as ji, presenceToCursors as jj, presentationBaseName as jk, presentationStageStyle as jl, presenterTimerProgress as jm, presetByLayout as jn, presetsForCategory as jo, pressuresToWidths as jp, prevVisibleIndex as jq, projectDrawingShapes as jr, promoteNode as js, provideViewerTheme as jt, radarAngle as ju, radarRingPoints as jv, readAsDataUrl as jw, recordWebm as jx, registerCrossSlideAudio as jy, rememberSessionDeck as jz, ActionSettingsPanelComponent as k, setSeriesName as k$, resolveSlideAutoAdvanceMs as k0, resolvePalette as k1, resolveThemeCatalogEntry as k2, resolveTransitionDuration as k3, restoreSessionDeck as k4, revealedElementStyles as k5, routeOrthogonalConnector as k6, rowStyle as k7, rulerDragToGuidePosition as k8, rulerHighlight as k9, setAxisLogScale as kA, setAxisTitleStyle as kB, setCategoryLabel as kC, setCellText as kD, setColorScheme as kE, setDataLabels as kF, setDataPointExplosion as kG, setDataPointFill as kH, setDataPointLabel as kI, setDataPointMarker as kJ, setDelay as kK, setDirection as kL, setDuration as kM, setEffectSound as kN, setElementPosition as kO, setGridlineStyle as kP, setLayout as kQ, setLegend as kR, setNodeStyle as kS, setNodeText as kT, setRepeatCount as kU, setRepeatMode as kV, setSequence as kW, setSeriesChartType as kX, setSeriesColor as kY, setSeriesErrorBars as kZ, setSeriesMarker as k_, rulerStripTicks as ka, sampleColorFromSlide as kb, sanitizeColor as kc, sanitizeSlideIndex as kd, sanitizeUserName as ke, saveViewerProfile as kf, savedPresentationFileName as kg, scanAvailableFonts as kh, searchSlides as ki, seedBroadcastFields as kj, seedHyperlinkDraft as kk, seedPropertiesDraft as kl, seedShareFields as km, segmentFrameCount as kn, selectValue$3 as ko, sendBackward as kp, sendToBack as kq, sequentialColorScale as kr, serializeWriteBack as ks, seriesColor as kt, setAfterAnimation as ku, setAfterAnimationColor as kv, setAnimationEmphasis as kw, setAnimationEntrance as kx, setAnimationExit as ky, setAxis as kz, AdvancedChartEditorComponent as l, valueToY as l$, setSeriesTrendline as l0, setSeriesValue as l1, setStyle as l2, setTimingCurve as l3, setTitle as l4, setTrigger as l5, setTriggerShapeId as l6, shapeStylePatch$1 as l7, sheetAfterNavigate as l8, shouldBlockClickAdvance as l9, textAdvancedStateOf as lA, textColorOf as lB, textDirectionPatch as lC, textFontSizePatch as lD, textStyleOf as lE, textStylePatch as lF, themeStyle as lG, themeToCssVars as lH, thumbnailHeight as lI, thumbnailZoom as lJ, toggleCommentResolvedInList as lK, toggleNodeBold as lL, toggleNodeItalic as lM, toggleSheet as lN, topLevelNodeCount as lO, transformSelectedTextCase as lP, translationsEn as lQ, updateElementById as lR, updateGlowPatch as lS, updateGradientStopPatch as lT, updateInnerShadowPatch as lU, updateOuterShadowPatch as lV, updateReflectionPatch as lW, vAlignPatch as lX, validatePassword as lY, validatePrintSettings as lZ, validateRoomId as l_, shouldUseSvgWarp as la, showDirectionPicker as lb, showsTemplateAffordance as lc, signatureCountLabel as ld, signatureKey as le, signatureTimestamp as lf, signerName as lg, statusLabel as lh, slideNumberOf as li, slidesWithReappliedLayout as lj, smartArtNodes as lk, paletteColour as ll, snapToGridStep as lm, splitCursorCell as ln, splitMergedCell as lo, statusKind as lp, statusLabel$1 as lq, storeAudienceContent as lr, stringFromEvent$5 as ls, strokeColorOf as lt, strokeToInkElement as lu, strokeWidthOf as lv, styleShadowFilter as lw, surfaceColor as lx, textAdvancedPatch as ly, textAdvancedStateFromStyle as lz, AiChangeOverlayComponent as m, vermilionDarkColors as m0, vermilionDarkTheme as m1, vermilionLightColors as m2, vermilionLightTheme as m3, vermilionRadius as m4, waypointsToPathD as m5, withManualLayouts as m6, worstStatus as m7, zoomTargetSlideIndex as m8, 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 };
|
|
167013
|
+
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-BzS7I0F9.mjs.map
|