pptx-angular-viewer 4.24.1 → 4.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -245,7 +245,7 @@ function getStrokeOnlyPresetPaths(element) {
245
245
  const shapeType = element.shapeType;
246
246
  if (!shapeType || shapeType === "custom") return;
247
247
  if (element.pathData) return;
248
- const result = evaluatePresetShape(shapeType, Math.max(element.width, 1), Math.max(element.height, 1), element.shapeAdjustments);
248
+ const result = evaluatePresetShape(shapeType, Math.max(element.width, 0), Math.max(element.height, 0), element.shapeAdjustments);
249
249
  if (!result || !result.fillNone) return;
250
250
  const drawable = result.paths.filter((path) => path.d !== "");
251
251
  return drawable.length > 0 ? drawable : void 0;
@@ -818,7 +818,10 @@ function buildStrokeOutline(element) {
818
818
  };
819
819
  }
820
820
  function strokeOutlineViewBox(element) {
821
- return `0 0 ${Math.max(element.width, 0)} ${Math.max(element.height, 0)}`;
821
+ const width = Math.max(element.width, 0);
822
+ const height = Math.max(element.height, 0);
823
+ if (width < 1 || height < 1) return;
824
+ return `0 0 ${width} ${height}`;
822
825
  }
823
826
  function suppressesCssBorder(element) {
824
827
  return buildStrokeOutline(element) !== void 0;
@@ -40117,19 +40120,152 @@ function buildSmartArt3DSpecForElement(element, options = {}) {
40117
40120
  });
40118
40121
  return model.meshes.length > 0 ? model : null;
40119
40122
  }
40123
+ const GEOMETRY_SELECTOR = "path, rect, polygon, polyline, ellipse, circle";
40124
+ function nodeShapeContainsPoint(node, x, y) {
40125
+ let tested = false;
40126
+ for (const shape of node.querySelectorAll(GEOMETRY_SELECTOR)) {
40127
+ const geometry = shape;
40128
+ const matrix = geometry.getScreenCTM?.();
40129
+ if (!matrix || typeof geometry.isPointInFill !== "function") continue;
40130
+ const det = matrix.a * matrix.d - matrix.b * matrix.c;
40131
+ if (!det) continue;
40132
+ tested = true;
40133
+ const dx = x - matrix.e;
40134
+ const dy = y - matrix.f;
40135
+ const local = {
40136
+ x: (matrix.d * dx - matrix.c * dy) / det,
40137
+ y: (matrix.a * dy - matrix.b * dx) / det
40138
+ };
40139
+ if (geometry.isPointInFill(local) || geometry.isPointInStroke?.(local)) return true;
40140
+ }
40141
+ return tested ? false : null;
40142
+ }
40120
40143
  function smartArtNodeAtPoint(root, x, y) {
40121
40144
  let best = null;
40122
40145
  let bestArea = Number.POSITIVE_INFINITY;
40123
40146
  for (const node of root.querySelectorAll("[data-smartart-node-id]")) {
40124
40147
  const box = node.getBoundingClientRect();
40125
40148
  const area = box.width * box.height;
40126
- if (area > 0 && x >= box.left && x <= box.right && y >= box.top && y <= box.bottom && area < bestArea) {
40149
+ if (area <= 0 || area >= bestArea) continue;
40150
+ if (nodeShapeContainsPoint(node, x, y) ?? (x >= box.left && x <= box.right && y >= box.top && y <= box.bottom)) {
40127
40151
  best = node;
40128
40152
  bestArea = area;
40129
40153
  }
40130
40154
  }
40131
40155
  return best;
40132
40156
  }
40157
+ function polygonBounds(points) {
40158
+ const pairs = points.trim().split(/\s+/u);
40159
+ let minX = Infinity;
40160
+ let minY = Infinity;
40161
+ let maxX = -Infinity;
40162
+ let maxY = -Infinity;
40163
+ for (const pair of pairs) {
40164
+ const comma = pair.indexOf(",");
40165
+ if (comma < 0) continue;
40166
+ const x = parseFloat(pair.slice(0, comma));
40167
+ const y = parseFloat(pair.slice(comma + 1));
40168
+ if (!isFinite(x) || !isFinite(y)) continue;
40169
+ if (x < minX) minX = x;
40170
+ if (x > maxX) maxX = x;
40171
+ if (y < minY) minY = y;
40172
+ if (y > maxY) maxY = y;
40173
+ }
40174
+ if (!isFinite(minX)) return {
40175
+ x: 0,
40176
+ y: 0,
40177
+ width: 0,
40178
+ height: 0
40179
+ };
40180
+ return {
40181
+ x: minX,
40182
+ y: minY,
40183
+ width: maxX - minX,
40184
+ height: maxY - minY
40185
+ };
40186
+ }
40187
+ function renderedNodeToShape(rn, nodeId, family) {
40188
+ const id = `reflow-${family}-${nodeId}`;
40189
+ const text = rn.text || void 0;
40190
+ if (rn.kind === "rect") return {
40191
+ id,
40192
+ shapeType: rn.rx > 0 ? "roundRect" : "rect",
40193
+ x: rn.x,
40194
+ y: rn.y,
40195
+ width: rn.width,
40196
+ height: rn.height,
40197
+ rotation: 0,
40198
+ fillColor: rn.fill,
40199
+ strokeColor: rn.stroke,
40200
+ strokeWidth: rn.strokeWidth,
40201
+ text,
40202
+ fontSize: rn.fontSize
40203
+ };
40204
+ if (rn.kind === "circle") return {
40205
+ id,
40206
+ shapeType: "ellipse",
40207
+ x: rn.cx - rn.r,
40208
+ y: rn.cy - rn.r,
40209
+ width: rn.r * 2,
40210
+ height: rn.r * 2,
40211
+ rotation: 0,
40212
+ fillColor: rn.fill,
40213
+ strokeColor: rn.stroke,
40214
+ strokeWidth: rn.strokeWidth,
40215
+ text,
40216
+ fontSize: rn.fontSize
40217
+ };
40218
+ const bounds = polygonBounds(rn.points);
40219
+ return {
40220
+ id,
40221
+ shapeType: "chevron",
40222
+ x: bounds.x,
40223
+ y: bounds.y,
40224
+ width: bounds.width,
40225
+ height: bounds.height,
40226
+ rotation: 0,
40227
+ fillColor: rn.fill,
40228
+ strokeColor: rn.stroke,
40229
+ strokeWidth: rn.strokeWidth,
40230
+ text,
40231
+ fontSize: rn.fontSize
40232
+ };
40233
+ }
40234
+ function reflowToDrawingShapes(layoutResult, nodes) {
40235
+ const flat = flattenNodes$1([...nodes]);
40236
+ const family = layoutResult.family;
40237
+ const shapes = [];
40238
+ for (let i = 0; i < layoutResult.nodes.length; i++) {
40239
+ const rn = layoutResult.nodes[i];
40240
+ const nodeId = flat[i]?.id ?? rn.key;
40241
+ shapes.push(renderedNodeToShape(rn, nodeId, family));
40242
+ }
40243
+ return shapes;
40244
+ }
40245
+ function rebuildDrawingShapesIfCleared(smartArtData, layout, palette, style, elementId, box) {
40246
+ const shapes = smartArtData.drawingShapes;
40247
+ if (shapes === void 0 || shapes.length > 0 || smartArtData.nodes.length === 0) return smartArtData;
40248
+ const layoutResult = computeSmartArtElementLayout({
40249
+ ...smartArtData,
40250
+ layout
40251
+ }, smartArtData.nodes, box, palette, style, elementId);
40252
+ return {
40253
+ ...smartArtData,
40254
+ drawingShapes: reflowToDrawingShapes(layoutResult, smartArtData.nodes)
40255
+ };
40256
+ }
40257
+ function reflowed(element, next) {
40258
+ return rebuildDrawingShapesIfCleared(next, next.layout, resolvePalette(next), next.style ?? "flat", element.id, {
40259
+ width: element.width,
40260
+ height: element.height
40261
+ });
40262
+ }
40263
+ function commitSmartArtNodeFill(element, nodeId, fill) {
40264
+ if (element.type !== "smartArt" || !element.smartArtData) return null;
40265
+ const data = element.smartArtData;
40266
+ const next = setSmartArtNodeStyle(data, nodeId, { fillColor: fill });
40267
+ return next === data ? null : reflowed(element, next);
40268
+ }
40133
40269
  const OBLIQUE_CATEGORY_LABEL_GAP = 14 * (4 / 3);
40134
40270
  const VALUE_GAP$1 = 18;
40135
40271
  const CATEGORY_GAP = OBLIQUE_CATEGORY_LABEL_GAP;
@@ -48183,106 +48319,6 @@ function createDefaultChartElement(chartKind = DEFAULT_INSERT_CHART_KIND, positi
48183
48319
  height: position?.height ?? DEFAULT_CHART_POSITION.height
48184
48320
  });
48185
48321
  }
48186
- function polygonBounds(points) {
48187
- const pairs = points.trim().split(/\s+/u);
48188
- let minX = Infinity;
48189
- let minY = Infinity;
48190
- let maxX = -Infinity;
48191
- let maxY = -Infinity;
48192
- for (const pair of pairs) {
48193
- const comma = pair.indexOf(",");
48194
- if (comma < 0) continue;
48195
- const x = parseFloat(pair.slice(0, comma));
48196
- const y = parseFloat(pair.slice(comma + 1));
48197
- if (!isFinite(x) || !isFinite(y)) continue;
48198
- if (x < minX) minX = x;
48199
- if (x > maxX) maxX = x;
48200
- if (y < minY) minY = y;
48201
- if (y > maxY) maxY = y;
48202
- }
48203
- if (!isFinite(minX)) return {
48204
- x: 0,
48205
- y: 0,
48206
- width: 0,
48207
- height: 0
48208
- };
48209
- return {
48210
- x: minX,
48211
- y: minY,
48212
- width: maxX - minX,
48213
- height: maxY - minY
48214
- };
48215
- }
48216
- function renderedNodeToShape(rn, nodeId, family) {
48217
- const id = `reflow-${family}-${nodeId}`;
48218
- const text = rn.text || void 0;
48219
- if (rn.kind === "rect") return {
48220
- id,
48221
- shapeType: rn.rx > 0 ? "roundRect" : "rect",
48222
- x: rn.x,
48223
- y: rn.y,
48224
- width: rn.width,
48225
- height: rn.height,
48226
- rotation: 0,
48227
- fillColor: rn.fill,
48228
- strokeColor: rn.stroke,
48229
- strokeWidth: rn.strokeWidth,
48230
- text,
48231
- fontSize: rn.fontSize
48232
- };
48233
- if (rn.kind === "circle") return {
48234
- id,
48235
- shapeType: "ellipse",
48236
- x: rn.cx - rn.r,
48237
- y: rn.cy - rn.r,
48238
- width: rn.r * 2,
48239
- height: rn.r * 2,
48240
- rotation: 0,
48241
- fillColor: rn.fill,
48242
- strokeColor: rn.stroke,
48243
- strokeWidth: rn.strokeWidth,
48244
- text,
48245
- fontSize: rn.fontSize
48246
- };
48247
- const bounds = polygonBounds(rn.points);
48248
- return {
48249
- id,
48250
- shapeType: "chevron",
48251
- x: bounds.x,
48252
- y: bounds.y,
48253
- width: bounds.width,
48254
- height: bounds.height,
48255
- rotation: 0,
48256
- fillColor: rn.fill,
48257
- strokeColor: rn.stroke,
48258
- strokeWidth: rn.strokeWidth,
48259
- text,
48260
- fontSize: rn.fontSize
48261
- };
48262
- }
48263
- function reflowToDrawingShapes(layoutResult, nodes) {
48264
- const flat = flattenNodes$1([...nodes]);
48265
- const family = layoutResult.family;
48266
- const shapes = [];
48267
- for (let i = 0; i < layoutResult.nodes.length; i++) {
48268
- const rn = layoutResult.nodes[i];
48269
- const nodeId = flat[i]?.id ?? rn.key;
48270
- shapes.push(renderedNodeToShape(rn, nodeId, family));
48271
- }
48272
- return shapes;
48273
- }
48274
- function rebuildDrawingShapesIfCleared(smartArtData, layout, palette, style, elementId, box) {
48275
- const shapes = smartArtData.drawingShapes;
48276
- if (shapes === void 0 || shapes.length > 0 || smartArtData.nodes.length === 0) return smartArtData;
48277
- const layoutResult = computeSmartArtElementLayout({
48278
- ...smartArtData,
48279
- layout
48280
- }, smartArtData.nodes, box, palette, style, elementId);
48281
- return {
48282
- ...smartArtData,
48283
- drawingShapes: reflowToDrawingShapes(layoutResult, smartArtData.nodes)
48284
- };
48285
- }
48286
48322
  function startMediaAutoplay(el, options) {
48287
48323
  const trimStartMs = options?.trimStartMs;
48288
48324
  if (trimStartMs !== void 0 && trimStartMs > 0) try {
@@ -61792,10 +61828,89 @@ function computeThreeViewSize(layoutWidth, layoutHeight, screenWidth, screenHeig
61792
61828
  pixelHeight: clamp(onScreenH * dpr)
61793
61829
  };
61794
61830
  }
61831
+ const IDENTITY = {
61832
+ a: 1,
61833
+ b: 0,
61834
+ c: 0,
61835
+ d: 1
61836
+ };
61837
+ function compose(outer, inner) {
61838
+ return {
61839
+ a: outer.a * inner.a + outer.c * inner.b,
61840
+ b: outer.b * inner.a + outer.d * inner.b,
61841
+ c: outer.a * inner.c + outer.c * inner.d,
61842
+ d: outer.b * inner.c + outer.d * inner.d
61843
+ };
61844
+ }
61845
+ function parseComputedTransform(value) {
61846
+ const match = /^(matrix3d|matrix)\(([^)]*)\)$/u.exec((value ?? "").trim());
61847
+ if (!match) return null;
61848
+ const n = (match[2] ?? "").split(",").map((part) => Number.parseFloat(part));
61849
+ const [a, b, c, d] = (match[1] === "matrix3d" ? [
61850
+ 0,
61851
+ 1,
61852
+ 4,
61853
+ 5
61854
+ ] : [
61855
+ 0,
61856
+ 1,
61857
+ 2,
61858
+ 3
61859
+ ]).map((i) => n[i]);
61860
+ return [
61861
+ a,
61862
+ b,
61863
+ c,
61864
+ d
61865
+ ].every((v) => v !== void 0 && Number.isFinite(v)) ? {
61866
+ a,
61867
+ b,
61868
+ c,
61869
+ d
61870
+ } : null;
61871
+ }
61872
+ function matrixScale(m) {
61873
+ return {
61874
+ x: Math.hypot(m.a, m.b),
61875
+ y: Math.hypot(m.c, m.d)
61876
+ };
61877
+ }
61878
+ function parentOf(node) {
61879
+ if (node.parentElement) return node.parentElement;
61880
+ const root = node.getRootNode?.();
61881
+ return root && "host" in root ? root.host ?? null : null;
61882
+ }
61883
+ function measureTransformScale(element) {
61884
+ const win = element.ownerDocument?.defaultView;
61885
+ if (!win) return {
61886
+ x: 1,
61887
+ y: 1
61888
+ };
61889
+ let total = IDENTITY;
61890
+ for (let node = element; node; node = parentOf(node)) {
61891
+ const style = win.getComputedStyle(node);
61892
+ if (style.scale && style.scale !== "none") {
61893
+ const [sx = "1", sy = sx] = style.scale.split(/\s+/u);
61894
+ const x = Number.parseFloat(sx);
61895
+ const y = Number.parseFloat(sy);
61896
+ if (Number.isFinite(x) && Number.isFinite(y)) total = compose({
61897
+ a: x,
61898
+ b: 0,
61899
+ c: 0,
61900
+ d: y
61901
+ }, total);
61902
+ }
61903
+ const transform = parseComputedTransform(style.transform);
61904
+ if (transform) total = compose(transform, total);
61905
+ }
61906
+ return matrixScale(total);
61907
+ }
61795
61908
  function measureThreeViewSize(element) {
61796
- const rect = element.getBoundingClientRect();
61797
61909
  const win = element.ownerDocument?.defaultView;
61798
- return computeThreeViewSize(element.clientWidth, element.clientHeight, rect.width, rect.height, win?.devicePixelRatio ?? 1);
61910
+ const layoutWidth = element.clientWidth;
61911
+ const layoutHeight = element.clientHeight;
61912
+ const scale = measureTransformScale(element);
61913
+ return computeThreeViewSize(layoutWidth, layoutHeight, layoutWidth * scale.x, layoutHeight * scale.y, win?.devicePixelRatio ?? 1);
61799
61914
  }
61800
61915
  const THREE_VIEW_TAG = "pptx-three-view";
61801
61916
  const THREE_VIEW_MARKER_ATTR = "data-pptx-three-view";
@@ -61969,6 +62084,7 @@ function createElementClass() {
61969
62084
  return PptxThreeView;
61970
62085
  }
61971
62086
  function defineThreeViewElement(registry) {
62087
+ if (typeof HTMLElement === "undefined") return;
61972
62088
  const target = registry ?? (typeof customElements === "undefined" ? void 0 : customElements);
61973
62089
  if (!target || target.get("pptx-three-view")) return;
61974
62090
  target.define(THREE_VIEW_TAG, createElementClass());
@@ -71450,7 +71566,10 @@ function buildSelectControl(ctx, control) {
71450
71566
  sync(state) {
71451
71567
  const current = state.controls[key];
71452
71568
  const label = homeLabel(state, control.labelKey, control.fallback);
71453
- if (select.getAttribute("aria-label") !== label) select.setAttribute("aria-label", label);
71569
+ if (select.getAttribute("aria-label") !== label) {
71570
+ select.setAttribute("aria-label", label);
71571
+ select.requestUpdate?.();
71572
+ }
71454
71573
  select.title = label;
71455
71574
  select.hidden = Boolean(current?.hidden);
71456
71575
  const { nodes, signature: next } = selectOptions(doc, current?.items ?? control.items ?? [], state);
@@ -93854,12 +93973,25 @@ i0.ɵɵngDeclareClassMetadata({
93854
93973
  function getSmartArtData(element) {
93855
93974
  return element.type === "smartArt" ? element.smartArtData : void 0;
93856
93975
  }
93857
- function computeNode3DEditBox(nodeRect, containerRect) {
93976
+ function toNode3DEditBox(rect) {
93858
93977
  return {
93859
- x: nodeRect.left - containerRect.left,
93860
- y: nodeRect.top - containerRect.top,
93861
- width: nodeRect.width,
93862
- height: nodeRect.height
93978
+ x: rect.left,
93979
+ y: rect.top,
93980
+ width: rect.width,
93981
+ height: rect.height
93982
+ };
93983
+ }
93984
+ const STYLE_BAR_WIDTH = 168;
93985
+ const STYLE_BAR_HEIGHT = 40;
93986
+ function computeNode3DStyleBarStyle(rect, container) {
93987
+ if (!rect || !container) return null;
93988
+ const maxLeft = Math.max(0, container.clientWidth - STYLE_BAR_WIDTH);
93989
+ const maxTop = Math.max(0, container.clientHeight - STYLE_BAR_HEIGHT);
93990
+ return {
93991
+ position: "absolute",
93992
+ left: `${Math.min(maxLeft, Math.max(0, rect.left + rect.width - STYLE_BAR_WIDTH))}px`,
93993
+ top: `${Math.min(maxTop, Math.max(0, rect.top - 22))}px`,
93994
+ "z-index": "25"
93863
93995
  };
93864
93996
  }
93865
93997
  var SmartArt3DRendererComponent = class SmartArt3DRendererComponent {
@@ -93885,6 +94017,10 @@ var SmartArt3DRendererComponent = class SmartArt3DRendererComponent {
93885
94017
  this.containerStyle = computed(() => getContainerStyle(this.element(), this.zIndex()), ...ngDevMode ? [{ debugName: "containerStyle" }] : /* istanbul ignore next */ []);
93886
94018
  this.hitTargetStyle = computed(() => shouldRenderHitTarget(this.editable(), this.presenting()) ? elementHitTargetStyle(this.element()) : void 0, ...ngDevMode ? [{ debugName: "hitTargetStyle" }] : /* istanbul ignore next */ []);
93887
94019
  this.smartArtData = computed(() => getSmartArtData(this.element()), ...ngDevMode ? [{ debugName: "smartArtData" }] : /* istanbul ignore next */ []);
94020
+ this.palette = computed(() => resolvePalette(this.smartArtData()), ...ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []);
94021
+ this.hoveredNodeId = signal(null, ...ngDevMode ? [{ debugName: "hoveredNodeId" }] : /* istanbul ignore next */ []);
94022
+ this.hoveredNodeRect = signal(null, ...ngDevMode ? [{ debugName: "hoveredNodeRect" }] : /* istanbul ignore next */ []);
94023
+ this.styleBarStyle = computed(() => computeNode3DStyleBarStyle(this.hoveredNodeRect(), this.containerEl()?.nativeElement), ...ngDevMode ? [{ debugName: "styleBarStyle" }] : /* istanbul ignore next */ []);
93888
94024
  effect(() => {
93889
94025
  if (this.editState()) afterNextRender(() => {
93890
94026
  const el = this.nodeEditor3d()?.nativeElement;
@@ -93902,17 +94038,45 @@ var SmartArt3DRendererComponent = class SmartArt3DRendererComponent {
93902
94038
  if (!container || !data || !(overlay instanceof Element)) return;
93903
94039
  const nodeEl = smartArtNodeAtPoint(overlay, event.clientX, event.clientY);
93904
94040
  const nodeId = nodeEl?.getAttribute("data-smartart-node-id");
93905
- if (!nodeEl || !nodeId) return;
94041
+ const rect = nodeEl ? measureSvgViewportRect(nodeEl) : null;
94042
+ if (!nodeEl || !nodeId || !rect) return;
93906
94043
  event.stopPropagation();
93907
94044
  const currentText = data.nodes.find((n) => n.id === nodeId)?.text ?? "";
93908
94045
  this.draftText = currentText;
93909
94046
  this.editSettled = false;
94047
+ this.hoveredNodeId.set(null);
94048
+ this.hoveredNodeRect.set(null);
93910
94049
  this.editState.set({
93911
94050
  nodeId,
93912
- box: computeNode3DEditBox(nodeEl.getBoundingClientRect(), container.getBoundingClientRect()),
94051
+ box: toNode3DEditBox(rect),
93913
94052
  text: currentText
93914
94053
  });
93915
94054
  }
94055
+ onOverlayMouseMove(event) {
94056
+ const overlay = event.currentTarget;
94057
+ if (!(overlay instanceof Element) || this.editState()) return;
94058
+ const nodeEl = smartArtNodeAtPoint(overlay, event.clientX, event.clientY);
94059
+ const id = nodeEl?.getAttribute("data-smartart-node-id") ?? null;
94060
+ if (id !== this.hoveredNodeId()) {
94061
+ this.hoveredNodeId.set(id);
94062
+ this.hoveredNodeRect.set(id && nodeEl ? measureSvgViewportRect(nodeEl) : null);
94063
+ }
94064
+ }
94065
+ onHoverLeave(event) {
94066
+ const to = event.relatedTarget;
94067
+ if (to instanceof Node && this.containerEl()?.nativeElement.contains(to)) return;
94068
+ this.hoveredNodeId.set(null);
94069
+ this.hoveredNodeRect.set(null);
94070
+ }
94071
+ handleChangeNodeStyle(nodeId, fill) {
94072
+ const next = commitSmartArtNodeFill(this.element(), nodeId, fill);
94073
+ if (!next || !this.editor) return;
94074
+ const slideIndex = findOwningSlideIndex(this.editor.slides(), this.element().id, this.slideContext?.slideId() ?? null);
94075
+ if (slideIndex < 0) return;
94076
+ this.hoveredNodeId.set(null);
94077
+ this.hoveredNodeRect.set(null);
94078
+ this.editor.updateElement(slideIndex, this.element().id, { smartArtData: next });
94079
+ }
93916
94080
  updateDraft(event) {
93917
94081
  this.draftText = event.target.value;
93918
94082
  }
@@ -94032,8 +94196,8 @@ var SmartArt3DRendererComponent = class SmartArt3DRendererComponent {
94032
94196
  isSignal: true
94033
94197
  }],
94034
94198
  ngImport: i0,
94035
- template: "@if (useFallback()) {\n <!--\n The SVG renderer only fills a box, so the positioned, id-bearing,\n marked element node has to be drawn here.\n -->\n <div\n class=\"pptx-ng-element pptx-ng-smartart\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-smart-art-renderer [element]=\"element()\" />\n </div>\n} @else {\n <div\n #container3d\n class=\"pptx-ng-element pptx-ng-smartart-3d\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-ng-three-view [spec]=\"spec()\" [interactive]=\"canEdit()\" [textStyle]=\"textStyle()\">\n <pptx-smart-art-renderer [element]=\"element()\" />\n </pptx-ng-three-view>\n @if (canEdit()) {\n <!-- Invisible SVG overlay: provides data-smartart-node-id hit targets -->\n <div class=\"pptx-ng-smartart-3d-hittest\" (dblclick)=\"onOverlayDblClick($event)\">\n <pptx-smart-art-renderer [element]=\"element()\" [editable]=\"false\" />\n </div>\n @if (editState()) {\n <textarea\n #nodeEditor3d\n class=\"pptx-ng-smartart-3d-node-editor\"\n [style.left.px]=\"editState()!.box.x\"\n [style.top.px]=\"editState()!.box.y\"\n [style.width.px]=\"editState()!.box.width\"\n [style.height.px]=\"editState()!.box.height\"\n [value]=\"editState()!.text\"\n spellcheck=\"false\"\n [attr.aria-label]=\"'pptx.smartArt.editNodeText' | translate\"\n (input)=\"updateDraft($event)\"\n (blur)=\"commitEdit()\"\n (keydown)=\"onEditorKeydown($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"$event.stopPropagation()\"\n ></textarea>\n }\n }\n </div>\n}\n",
94036
- styles: [".pptx-ng-smartart-3d-hittest{position:absolute;inset:0;opacity:0;pointer-events:auto}.pptx-ng-smartart-3d-node-editor{position:absolute;box-sizing:border-box;margin:0;padding:1px 2px;border:1px solid var(--pptx-inspector-active, #0078d4);border-radius:2px;background:#fff;color:#111;font-size:11px;line-height:1.1;text-align:center;resize:none;overflow:hidden;z-index:20;outline:none}\n"],
94199
+ template: "@if (useFallback()) {\n <!--\n The SVG renderer only fills a box, so the positioned, id-bearing,\n marked element node has to be drawn here.\n -->\n <div\n class=\"pptx-ng-element pptx-ng-smartart\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-smart-art-renderer [element]=\"element()\" />\n </div>\n} @else {\n <div\n #container3d\n class=\"pptx-ng-element pptx-ng-smartart-3d\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-ng-three-view [spec]=\"spec()\" [interactive]=\"canEdit()\" [textStyle]=\"textStyle()\">\n <pptx-smart-art-renderer [element]=\"element()\" />\n </pptx-ng-three-view>\n @if (canEdit()) {\n <!-- Invisible SVG overlay: provides data-smartart-node-id hit targets -->\n <div\n class=\"pptx-ng-smartart-3d-hittest\"\n (dblclick)=\"onOverlayDblClick($event)\"\n (mousemove)=\"onOverlayMouseMove($event)\"\n (mouseleave)=\"onHoverLeave($event)\"\n >\n <pptx-smart-art-renderer [element]=\"element()\" [editable]=\"false\" />\n </div>\n @if (hoveredNodeId() && !editState() && styleBarStyle()) {\n <!-- Per-node fill colour picker (hover swatch bar), as on the 2D diagram -->\n <div\n class=\"pptx-ng-smartart-3d-style-bar\"\n [ngStyle]=\"styleBarStyle()!\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (mouseleave)=\"onHoverLeave($event)\"\n >\n @for (color of palette().slice(0, 6); track color) {\n <button\n type=\"button\"\n class=\"pptx-ng-smartart-3d-swatch\"\n data-pptx-compact\n [attr.aria-label]=\"'pptx.smartArt.setFill' | translate: { color: color }\"\n [style.background]=\"color\"\n (click)=\"handleChangeNodeStyle(hoveredNodeId()!, color)\"\n ></button>\n }\n </div>\n }\n @if (editState()) {\n <textarea\n #nodeEditor3d\n class=\"pptx-ng-smartart-3d-node-editor\"\n [style.left.px]=\"editState()!.box.x\"\n [style.top.px]=\"editState()!.box.y\"\n [style.width.px]=\"editState()!.box.width\"\n [style.height.px]=\"editState()!.box.height\"\n [value]=\"editState()!.text\"\n spellcheck=\"false\"\n [attr.aria-label]=\"'pptx.smartArt.editNodeText' | translate\"\n (input)=\"updateDraft($event)\"\n (blur)=\"commitEdit()\"\n (keydown)=\"onEditorKeydown($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"$event.stopPropagation()\"\n ></textarea>\n }\n }\n </div>\n}\n",
94200
+ styles: [".pptx-ng-smartart-3d-hittest{position:absolute;inset:0;opacity:0;pointer-events:auto}.pptx-ng-smartart-3d-node-editor{position:absolute;box-sizing:border-box;margin:0;padding:1px 2px;border:1px solid var(--pptx-inspector-active, #0078d4);border-radius:2px;background:#fff;color:#111;font-size:11px;line-height:1.1;text-align:center;resize:none;overflow:hidden;z-index:20;outline:none}.pptx-ng-smartart-3d-style-bar{position:absolute;pointer-events:auto;display:flex;gap:6px;padding:6px 8px;background:#ffffffe6;border:1px solid var(--border, #e2e8f0);border-radius:9999px;box-shadow:0 1px 2px #0000001a}.pptx-ng-smartart-3d-swatch{width:20px;height:20px;border-radius:50%;border:1px solid rgba(0,0,0,.1);cursor:pointer;transition:transform .1s}.pptx-ng-smartart-3d-swatch:hover{transform:scale(1.25)}\n"],
94037
94201
  dependencies: [
94038
94202
  {
94039
94203
  kind: "directive",
@@ -94094,8 +94258,8 @@ i0.ɵɵngDeclareClassMetadata({
94094
94258
  ThreeViewComponent,
94095
94259
  TranslatePipe
94096
94260
  ],
94097
- template: "@if (useFallback()) {\n <!--\n The SVG renderer only fills a box, so the positioned, id-bearing,\n marked element node has to be drawn here.\n -->\n <div\n class=\"pptx-ng-element pptx-ng-smartart\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-smart-art-renderer [element]=\"element()\" />\n </div>\n} @else {\n <div\n #container3d\n class=\"pptx-ng-element pptx-ng-smartart-3d\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-ng-three-view [spec]=\"spec()\" [interactive]=\"canEdit()\" [textStyle]=\"textStyle()\">\n <pptx-smart-art-renderer [element]=\"element()\" />\n </pptx-ng-three-view>\n @if (canEdit()) {\n <!-- Invisible SVG overlay: provides data-smartart-node-id hit targets -->\n <div class=\"pptx-ng-smartart-3d-hittest\" (dblclick)=\"onOverlayDblClick($event)\">\n <pptx-smart-art-renderer [element]=\"element()\" [editable]=\"false\" />\n </div>\n @if (editState()) {\n <textarea\n #nodeEditor3d\n class=\"pptx-ng-smartart-3d-node-editor\"\n [style.left.px]=\"editState()!.box.x\"\n [style.top.px]=\"editState()!.box.y\"\n [style.width.px]=\"editState()!.box.width\"\n [style.height.px]=\"editState()!.box.height\"\n [value]=\"editState()!.text\"\n spellcheck=\"false\"\n [attr.aria-label]=\"'pptx.smartArt.editNodeText' | translate\"\n (input)=\"updateDraft($event)\"\n (blur)=\"commitEdit()\"\n (keydown)=\"onEditorKeydown($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"$event.stopPropagation()\"\n ></textarea>\n }\n }\n </div>\n}\n",
94098
- styles: [".pptx-ng-smartart-3d-hittest{position:absolute;inset:0;opacity:0;pointer-events:auto}.pptx-ng-smartart-3d-node-editor{position:absolute;box-sizing:border-box;margin:0;padding:1px 2px;border:1px solid var(--pptx-inspector-active, #0078d4);border-radius:2px;background:#fff;color:#111;font-size:11px;line-height:1.1;text-align:center;resize:none;overflow:hidden;z-index:20;outline:none}\n"]
94261
+ template: "@if (useFallback()) {\n <!--\n The SVG renderer only fills a box, so the positioned, id-bearing,\n marked element node has to be drawn here.\n -->\n <div\n class=\"pptx-ng-element pptx-ng-smartart\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-smart-art-renderer [element]=\"element()\" />\n </div>\n} @else {\n <div\n #container3d\n class=\"pptx-ng-element pptx-ng-smartart-3d\"\n [ngStyle]=\"containerStyle()\"\n [attr.data-element-id]=\"element().id\"\n [attr.data-pptx-element]=\"markElement() ? 'true' : null\"\n >\n <!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <pptx-ng-three-view [spec]=\"spec()\" [interactive]=\"canEdit()\" [textStyle]=\"textStyle()\">\n <pptx-smart-art-renderer [element]=\"element()\" />\n </pptx-ng-three-view>\n @if (canEdit()) {\n <!-- Invisible SVG overlay: provides data-smartart-node-id hit targets -->\n <div\n class=\"pptx-ng-smartart-3d-hittest\"\n (dblclick)=\"onOverlayDblClick($event)\"\n (mousemove)=\"onOverlayMouseMove($event)\"\n (mouseleave)=\"onHoverLeave($event)\"\n >\n <pptx-smart-art-renderer [element]=\"element()\" [editable]=\"false\" />\n </div>\n @if (hoveredNodeId() && !editState() && styleBarStyle()) {\n <!-- Per-node fill colour picker (hover swatch bar), as on the 2D diagram -->\n <div\n class=\"pptx-ng-smartart-3d-style-bar\"\n [ngStyle]=\"styleBarStyle()!\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (mouseleave)=\"onHoverLeave($event)\"\n >\n @for (color of palette().slice(0, 6); track color) {\n <button\n type=\"button\"\n class=\"pptx-ng-smartart-3d-swatch\"\n data-pptx-compact\n [attr.aria-label]=\"'pptx.smartArt.setFill' | translate: { color: color }\"\n [style.background]=\"color\"\n (click)=\"handleChangeNodeStyle(hoveredNodeId()!, color)\"\n ></button>\n }\n </div>\n }\n @if (editState()) {\n <textarea\n #nodeEditor3d\n class=\"pptx-ng-smartart-3d-node-editor\"\n [style.left.px]=\"editState()!.box.x\"\n [style.top.px]=\"editState()!.box.y\"\n [style.width.px]=\"editState()!.box.width\"\n [style.height.px]=\"editState()!.box.height\"\n [value]=\"editState()!.text\"\n spellcheck=\"false\"\n [attr.aria-label]=\"'pptx.smartArt.editNodeText' | translate\"\n (input)=\"updateDraft($event)\"\n (blur)=\"commitEdit()\"\n (keydown)=\"onEditorKeydown($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (dblclick)=\"$event.stopPropagation()\"\n ></textarea>\n }\n }\n </div>\n}\n",
94262
+ styles: [".pptx-ng-smartart-3d-hittest{position:absolute;inset:0;opacity:0;pointer-events:auto}.pptx-ng-smartart-3d-node-editor{position:absolute;box-sizing:border-box;margin:0;padding:1px 2px;border:1px solid var(--pptx-inspector-active, #0078d4);border-radius:2px;background:#fff;color:#111;font-size:11px;line-height:1.1;text-align:center;resize:none;overflow:hidden;z-index:20;outline:none}.pptx-ng-smartart-3d-style-bar{position:absolute;pointer-events:auto;display:flex;gap:6px;padding:6px 8px;background:#ffffffe6;border:1px solid var(--border, #e2e8f0);border-radius:9999px;box-shadow:0 1px 2px #0000001a}.pptx-ng-smartart-3d-swatch{width:20px;height:20px;border-radius:50%;border:1px solid rgba(0,0,0,.1);cursor:pointer;transition:transform .1s}.pptx-ng-smartart-3d-swatch:hover{transform:scale(1.25)}\n"]
94099
94263
  }]
94100
94264
  }],
94101
94265
  ctorParameters: () => [],
@@ -96615,6 +96779,8 @@ var ReflectionMirrorContentComponent = class ReflectionMirrorContentComponent {
96615
96779
  inset: 0;
96616
96780
  width: 100%;
96617
96781
  height: 100%;
96782
+ min-width: 1px;
96783
+ min-height: 1px;
96618
96784
  overflow: visible;
96619
96785
  pointer-events: none;
96620
96786
  "
@@ -96808,6 +96974,8 @@ i0.ɵɵngDeclareClassMetadata({
96808
96974
  inset: 0;
96809
96975
  width: 100%;
96810
96976
  height: 100%;
96977
+ min-width: 1px;
96978
+ min-height: 1px;
96811
96979
  overflow: visible;
96812
96980
  pointer-events: none;
96813
96981
  "
@@ -97183,7 +97351,7 @@ var ElementRendererShapeComponent = class ElementRendererShapeComponent {
97183
97351
  }
97184
97352
  },
97185
97353
  ngImport: i0,
97186
- template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n",
97354
+ template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n",
97187
97355
  dependencies: [
97188
97356
  {
97189
97357
  kind: "directive",
@@ -97249,7 +97417,7 @@ i0.ɵɵngDeclareClassMetadata({
97249
97417
  ReflectionMirrorContentComponent,
97250
97418
  SlideTextBlockComponent
97251
97419
  ],
97252
- template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n"
97420
+ template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n"
97253
97421
  }]
97254
97422
  }],
97255
97423
  propDecorators: {
@@ -121394,7 +121562,7 @@ i0.ɵɵngDeclareClassMetadata({
121394
121562
  }]
121395
121563
  }
121396
121564
  });
121397
- const PPTX_ANGULAR_VIEWER_VERSION = "4.24.0";
121565
+ const PPTX_ANGULAR_VIEWER_VERSION = "4.24.2";
121398
121566
  var AccountPageComponent = class AccountPageComponent {
121399
121567
  constructor() {
121400
121568
  this.accountAuth = input(void 0, ...ngDevMode ? [{ debugName: "accountAuth" }] : /* istanbul ignore next */ []);