pptx-react-viewer 1.1.4 → 1.1.6
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/dist/index.js +865 -159
- package/dist/index.mjs +866 -161
- package/dist/viewer/index.js +883 -165
- package/dist/viewer/index.mjs +884 -167
- package/node_modules/emf-converter/dist/index.d.mts +2 -2
- package/node_modules/emf-converter/dist/index.d.ts +2 -2
- package/node_modules/emf-converter/dist/index.js +91 -33
- package/node_modules/emf-converter/dist/index.mjs +91 -33
- package/node_modules/emf-converter/package.json +1 -1
- package/node_modules/mtx-decompressor/dist/index.js +39 -9
- package/node_modules/mtx-decompressor/dist/index.mjs +39 -9
- package/node_modules/mtx-decompressor/package.json +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-BQ4KbRO9.d.mts → SvgExporter-BTkk4oNQ.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-0TxiiorD.d.ts → SvgExporter-CTDG-t_z.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.js +0 -0
- package/node_modules/pptx-viewer-core/dist/cli/index.mjs +0 -0
- package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.js +0 -0
- package/node_modules/pptx-viewer-core/dist/converter/index.mjs +0 -0
- package/node_modules/pptx-viewer-core/dist/index.d.mts +961 -59
- package/node_modules/pptx-viewer-core/dist/index.d.ts +961 -59
- package/node_modules/pptx-viewer-core/dist/index.js +29880 -16692
- package/node_modules/pptx-viewer-core/dist/index.mjs +29859 -16692
- package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.mts → presentation-4fhI3din.d.mts} +835 -26
- package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.ts → presentation-4fhI3din.d.ts} +835 -26
- package/node_modules/pptx-viewer-core/dist/{signature-inspection-status-BcJSdOvb.d.mts → signature-inspection-status-BCUpfCQh.d.mts} +13 -2
- package/node_modules/pptx-viewer-core/dist/{signature-inspection-status-BcJSdOvb.d.ts → signature-inspection-status-BCUpfCQh.d.ts} +13 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.js +17 -3
- package/node_modules/pptx-viewer-core/dist/signature-node/index.mjs +16 -4
- package/node_modules/pptx-viewer-core/dist/{text-operations-rhJV-A_W.d.ts → text-operations-B9EwbptL.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-CLj-sJyk.d.mts → text-operations-C89Jn6S0.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/package.json +1 -1
- package/package.json +6 -4
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as React10 from 'react';
|
|
2
|
-
import React10__default, { createContext, useState, useEffect, useMemo, Suspense, useCallback, forwardRef, useRef, useSyncExternalStore, useImperativeHandle, useContext, useLayoutEffect } from 'react';
|
|
2
|
+
import React10__default, { createContext, useState, useEffect, useMemo, Suspense, useCallback, forwardRef, useRef, useSyncExternalStore, useImperativeHandle, useContext, useLayoutEffect, useDeferredValue } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import * as ReactDOM from 'react-dom/client';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import { LuMessageSquare, LuEyeOff, LuSettings, LuX, LuCast, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuClock, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuFileText, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMonitorOff, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuUndo, LuRedo, LuSearch, LuShare2, LuPanelRight, LuFolderOpen, LuVideo, LuImage, LuClipboardPaste, LuScissors, LuPaintbrush, LuChevronDown, LuSquare, LuDatabase, LuLayers, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuChevronUp, LuPalette, LuPencil, LuPaintBucket, LuSparkles, LuCaptions, LuSpellCheck, LuGitCompare, LuPipette, LuCaseSensitive, LuReplace, LuTimer, LuMousePointer2, LuEraser, LuGripVertical, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuEllipsis, LuCircle, LuMoveRight, LuTriangle, LuDiamond, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuSpline, LuSettings2, LuMove, LuRadio, LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
|
|
8
|
-
import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, isInkElement, getLinkedTextBoxSegments, isImageLikeElement, getSubstituteFontFamily, PptxHandler, EncryptedFileError, guidePxToEmu, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hslToRgb, PRESET_COLOR_MAP, elementActionToPptxAction, mergeShapes, SvgExporter, applyDrawingColorTransforms as applyDrawingColorTransforms$1, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, EMU_PER_PX as EMU_PER_PX$1, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, getOleObjectTypeLabel, pptxActionToElementAction, hasNonTrivialOverride, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, updateSmartArtNodeText, removeSmartArtNode, switchSmartArtLayout } from 'pptx-viewer-core';
|
|
8
|
+
import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, isInkElement, getLinkedTextBoxSegments, isImageLikeElement, getSubstituteFontFamily, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, PptxHandler, EncryptedFileError, guidePxToEmu, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hslToRgb, PRESET_COLOR_MAP, elementActionToPptxAction, mergeShapes, SvgExporter, applyDrawingColorTransforms as applyDrawingColorTransforms$1, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, EMU_PER_PX as EMU_PER_PX$1, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, getOleObjectTypeLabel, pptxActionToElementAction, hasNonTrivialOverride, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, updateSmartArtNodeText, removeSmartArtNode, switchSmartArtLayout } from 'pptx-viewer-core';
|
|
9
|
+
import DOMPurify from 'dompurify';
|
|
9
10
|
import { useTranslation } from 'react-i18next';
|
|
10
11
|
import html2canvasPro from 'html2canvas-pro';
|
|
11
12
|
import JSZip from 'jszip';
|
|
@@ -170,7 +171,7 @@ function generateUUID() {
|
|
|
170
171
|
const uuid = _lut[d0 & 255] + _lut[d0 >> 8 & 255] + _lut[d0 >> 16 & 255] + _lut[d0 >> 24 & 255] + "-" + _lut[d1 & 255] + _lut[d1 >> 8 & 255] + "-" + _lut[d1 >> 16 & 15 | 64] + _lut[d1 >> 24 & 255] + "-" + _lut[d2 & 63 | 128] + _lut[d2 >> 8 & 255] + "-" + _lut[d2 >> 16 & 255] + _lut[d2 >> 24 & 255] + _lut[d3 & 255] + _lut[d3 >> 8 & 255] + _lut[d3 >> 16 & 255] + _lut[d3 >> 24 & 255];
|
|
171
172
|
return uuid.toLowerCase();
|
|
172
173
|
}
|
|
173
|
-
function
|
|
174
|
+
function clamp2(value, min2, max2) {
|
|
174
175
|
return Math.max(min2, Math.min(max2, value));
|
|
175
176
|
}
|
|
176
177
|
function euclideanModulo(n, m2) {
|
|
@@ -545,7 +546,7 @@ function _generateTables() {
|
|
|
545
546
|
}
|
|
546
547
|
function toHalfFloat(val2) {
|
|
547
548
|
if (Math.abs(val2) > 65504) warn("DataUtils.toHalfFloat(): Value out of range.");
|
|
548
|
-
val2 =
|
|
549
|
+
val2 = clamp2(val2, -65504, 65504);
|
|
549
550
|
_tables.floatView[0] = val2;
|
|
550
551
|
const f = _tables.uint32View[0];
|
|
551
552
|
const e2 = f >> 23 & 511;
|
|
@@ -2034,7 +2035,7 @@ var init_three_core = __esm({
|
|
|
2034
2035
|
* @param {number} max - The max value.
|
|
2035
2036
|
* @return {number} The clamped value.
|
|
2036
2037
|
*/
|
|
2037
|
-
clamp,
|
|
2038
|
+
clamp: clamp2,
|
|
2038
2039
|
/**
|
|
2039
2040
|
* Computes the Euclidean modulo of the given parameters that
|
|
2040
2041
|
* is `( ( n % m ) + m ) % m`.
|
|
@@ -2561,8 +2562,8 @@ var init_three_core = __esm({
|
|
|
2561
2562
|
* @return {Vector2} A reference to this vector.
|
|
2562
2563
|
*/
|
|
2563
2564
|
clamp(min2, max2) {
|
|
2564
|
-
this.x =
|
|
2565
|
-
this.y =
|
|
2565
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
2566
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
2566
2567
|
return this;
|
|
2567
2568
|
}
|
|
2568
2569
|
/**
|
|
@@ -2576,8 +2577,8 @@ var init_three_core = __esm({
|
|
|
2576
2577
|
* @return {Vector2} A reference to this vector.
|
|
2577
2578
|
*/
|
|
2578
2579
|
clampScalar(minVal, maxVal) {
|
|
2579
|
-
this.x =
|
|
2580
|
-
this.y =
|
|
2580
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
2581
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
2581
2582
|
return this;
|
|
2582
2583
|
}
|
|
2583
2584
|
/**
|
|
@@ -2592,7 +2593,7 @@ var init_three_core = __esm({
|
|
|
2592
2593
|
*/
|
|
2593
2594
|
clampLength(min2, max2) {
|
|
2594
2595
|
const length2 = this.length();
|
|
2595
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
2596
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
2596
2597
|
}
|
|
2597
2598
|
/**
|
|
2598
2599
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -2717,7 +2718,7 @@ var init_three_core = __esm({
|
|
|
2717
2718
|
const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
|
|
2718
2719
|
if (denominator === 0) return Math.PI / 2;
|
|
2719
2720
|
const theta = this.dot(v) / denominator;
|
|
2720
|
-
return Math.acos(
|
|
2721
|
+
return Math.acos(clamp2(theta, -1, 1));
|
|
2721
2722
|
}
|
|
2722
2723
|
/**
|
|
2723
2724
|
* Computes the distance from the given vector to this instance.
|
|
@@ -3204,7 +3205,7 @@ var init_three_core = __esm({
|
|
|
3204
3205
|
* @return {number} The angle in radians.
|
|
3205
3206
|
*/
|
|
3206
3207
|
angleTo(q) {
|
|
3207
|
-
return 2 * Math.acos(Math.abs(
|
|
3208
|
+
return 2 * Math.acos(Math.abs(clamp2(this.dot(q), -1, 1)));
|
|
3208
3209
|
}
|
|
3209
3210
|
/**
|
|
3210
3211
|
* Rotates this quaternion by a given angular step to the given quaternion.
|
|
@@ -3910,9 +3911,9 @@ var init_three_core = __esm({
|
|
|
3910
3911
|
* @return {Vector3} A reference to this vector.
|
|
3911
3912
|
*/
|
|
3912
3913
|
clamp(min2, max2) {
|
|
3913
|
-
this.x =
|
|
3914
|
-
this.y =
|
|
3915
|
-
this.z =
|
|
3914
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
3915
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
3916
|
+
this.z = clamp2(this.z, min2.z, max2.z);
|
|
3916
3917
|
return this;
|
|
3917
3918
|
}
|
|
3918
3919
|
/**
|
|
@@ -3926,9 +3927,9 @@ var init_three_core = __esm({
|
|
|
3926
3927
|
* @return {Vector3} A reference to this vector.
|
|
3927
3928
|
*/
|
|
3928
3929
|
clampScalar(minVal, maxVal) {
|
|
3929
|
-
this.x =
|
|
3930
|
-
this.y =
|
|
3931
|
-
this.z =
|
|
3930
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
3931
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
3932
|
+
this.z = clamp2(this.z, minVal, maxVal);
|
|
3932
3933
|
return this;
|
|
3933
3934
|
}
|
|
3934
3935
|
/**
|
|
@@ -3943,7 +3944,7 @@ var init_three_core = __esm({
|
|
|
3943
3944
|
*/
|
|
3944
3945
|
clampLength(min2, max2) {
|
|
3945
3946
|
const length2 = this.length();
|
|
3946
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
3947
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
3947
3948
|
}
|
|
3948
3949
|
/**
|
|
3949
3950
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -4153,7 +4154,7 @@ var init_three_core = __esm({
|
|
|
4153
4154
|
const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
|
|
4154
4155
|
if (denominator === 0) return Math.PI / 2;
|
|
4155
4156
|
const theta = this.dot(v) / denominator;
|
|
4156
|
-
return Math.acos(
|
|
4157
|
+
return Math.acos(clamp2(theta, -1, 1));
|
|
4157
4158
|
}
|
|
4158
4159
|
/**
|
|
4159
4160
|
* Computes the distance from the given vector to this instance.
|
|
@@ -5842,10 +5843,10 @@ var init_three_core = __esm({
|
|
|
5842
5843
|
* @return {Vector4} A reference to this vector.
|
|
5843
5844
|
*/
|
|
5844
5845
|
clamp(min2, max2) {
|
|
5845
|
-
this.x =
|
|
5846
|
-
this.y =
|
|
5847
|
-
this.z =
|
|
5848
|
-
this.w =
|
|
5846
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
5847
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
5848
|
+
this.z = clamp2(this.z, min2.z, max2.z);
|
|
5849
|
+
this.w = clamp2(this.w, min2.w, max2.w);
|
|
5849
5850
|
return this;
|
|
5850
5851
|
}
|
|
5851
5852
|
/**
|
|
@@ -5859,10 +5860,10 @@ var init_three_core = __esm({
|
|
|
5859
5860
|
* @return {Vector4} A reference to this vector.
|
|
5860
5861
|
*/
|
|
5861
5862
|
clampScalar(minVal, maxVal) {
|
|
5862
|
-
this.x =
|
|
5863
|
-
this.y =
|
|
5864
|
-
this.z =
|
|
5865
|
-
this.w =
|
|
5863
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
5864
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
5865
|
+
this.z = clamp2(this.z, minVal, maxVal);
|
|
5866
|
+
this.w = clamp2(this.w, minVal, maxVal);
|
|
5866
5867
|
return this;
|
|
5867
5868
|
}
|
|
5868
5869
|
/**
|
|
@@ -5877,7 +5878,7 @@ var init_three_core = __esm({
|
|
|
5877
5878
|
*/
|
|
5878
5879
|
clampLength(min2, max2) {
|
|
5879
5880
|
const length2 = this.length();
|
|
5880
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
5881
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
5881
5882
|
}
|
|
5882
5883
|
/**
|
|
5883
5884
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -7660,7 +7661,7 @@ var init_three_core = __esm({
|
|
|
7660
7661
|
const m31 = te[2], m32 = te[6], m33 = te[10];
|
|
7661
7662
|
switch (order) {
|
|
7662
7663
|
case "XYZ":
|
|
7663
|
-
this._y = Math.asin(
|
|
7664
|
+
this._y = Math.asin(clamp2(m13, -1, 1));
|
|
7664
7665
|
if (Math.abs(m13) < 0.9999999) {
|
|
7665
7666
|
this._x = Math.atan2(-m23, m33);
|
|
7666
7667
|
this._z = Math.atan2(-m12, m11);
|
|
@@ -7670,7 +7671,7 @@ var init_three_core = __esm({
|
|
|
7670
7671
|
}
|
|
7671
7672
|
break;
|
|
7672
7673
|
case "YXZ":
|
|
7673
|
-
this._x = Math.asin(-
|
|
7674
|
+
this._x = Math.asin(-clamp2(m23, -1, 1));
|
|
7674
7675
|
if (Math.abs(m23) < 0.9999999) {
|
|
7675
7676
|
this._y = Math.atan2(m13, m33);
|
|
7676
7677
|
this._z = Math.atan2(m21, m22);
|
|
@@ -7680,7 +7681,7 @@ var init_three_core = __esm({
|
|
|
7680
7681
|
}
|
|
7681
7682
|
break;
|
|
7682
7683
|
case "ZXY":
|
|
7683
|
-
this._x = Math.asin(
|
|
7684
|
+
this._x = Math.asin(clamp2(m32, -1, 1));
|
|
7684
7685
|
if (Math.abs(m32) < 0.9999999) {
|
|
7685
7686
|
this._y = Math.atan2(-m31, m33);
|
|
7686
7687
|
this._z = Math.atan2(-m12, m22);
|
|
@@ -7690,7 +7691,7 @@ var init_three_core = __esm({
|
|
|
7690
7691
|
}
|
|
7691
7692
|
break;
|
|
7692
7693
|
case "ZYX":
|
|
7693
|
-
this._y = Math.asin(-
|
|
7694
|
+
this._y = Math.asin(-clamp2(m31, -1, 1));
|
|
7694
7695
|
if (Math.abs(m31) < 0.9999999) {
|
|
7695
7696
|
this._x = Math.atan2(m32, m33);
|
|
7696
7697
|
this._z = Math.atan2(m21, m11);
|
|
@@ -7700,7 +7701,7 @@ var init_three_core = __esm({
|
|
|
7700
7701
|
}
|
|
7701
7702
|
break;
|
|
7702
7703
|
case "YZX":
|
|
7703
|
-
this._z = Math.asin(
|
|
7704
|
+
this._z = Math.asin(clamp2(m21, -1, 1));
|
|
7704
7705
|
if (Math.abs(m21) < 0.9999999) {
|
|
7705
7706
|
this._x = Math.atan2(-m23, m22);
|
|
7706
7707
|
this._y = Math.atan2(-m31, m11);
|
|
@@ -7710,7 +7711,7 @@ var init_three_core = __esm({
|
|
|
7710
7711
|
}
|
|
7711
7712
|
break;
|
|
7712
7713
|
case "XZY":
|
|
7713
|
-
this._z = Math.asin(-
|
|
7714
|
+
this._z = Math.asin(-clamp2(m12, -1, 1));
|
|
7714
7715
|
if (Math.abs(m12) < 0.9999999) {
|
|
7715
7716
|
this._x = Math.atan2(m32, m22);
|
|
7716
7717
|
this._y = Math.atan2(m13, m11);
|
|
@@ -9334,8 +9335,8 @@ var init_three_core = __esm({
|
|
|
9334
9335
|
*/
|
|
9335
9336
|
setHSL(h2, s, l2, colorSpace = ColorManagement.workingColorSpace) {
|
|
9336
9337
|
h2 = euclideanModulo(h2, 1);
|
|
9337
|
-
s =
|
|
9338
|
-
l2 =
|
|
9338
|
+
s = clamp2(s, 0, 1);
|
|
9339
|
+
l2 = clamp2(l2, 0, 1);
|
|
9339
9340
|
if (s === 0) {
|
|
9340
9341
|
this.r = this.g = this.b = l2;
|
|
9341
9342
|
} else {
|
|
@@ -9521,7 +9522,7 @@ var init_three_core = __esm({
|
|
|
9521
9522
|
*/
|
|
9522
9523
|
getHex(colorSpace = SRGBColorSpace) {
|
|
9523
9524
|
ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);
|
|
9524
|
-
return Math.round(
|
|
9525
|
+
return Math.round(clamp2(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp2(_color.g * 255, 0, 255)) * 256 + Math.round(clamp2(_color.b * 255, 0, 255));
|
|
9525
9526
|
}
|
|
9526
9527
|
/**
|
|
9527
9528
|
* Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').
|
|
@@ -18452,13 +18453,13 @@ var init_three_core = __esm({
|
|
|
18452
18453
|
vec.crossVectors(tangents[i3 - 1], tangents[i3]);
|
|
18453
18454
|
if (vec.length() > Number.EPSILON) {
|
|
18454
18455
|
vec.normalize();
|
|
18455
|
-
const theta = Math.acos(
|
|
18456
|
+
const theta = Math.acos(clamp2(tangents[i3 - 1].dot(tangents[i3]), -1, 1));
|
|
18456
18457
|
normals[i3].applyMatrix4(mat.makeRotationAxis(vec, theta));
|
|
18457
18458
|
}
|
|
18458
18459
|
binormals[i3].crossVectors(tangents[i3], normals[i3]);
|
|
18459
18460
|
}
|
|
18460
18461
|
if (closed === true) {
|
|
18461
|
-
let theta = Math.acos(
|
|
18462
|
+
let theta = Math.acos(clamp2(normals[0].dot(normals[segments]), -1, 1));
|
|
18462
18463
|
theta /= segments;
|
|
18463
18464
|
if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
|
|
18464
18465
|
theta = -theta;
|
|
@@ -20247,7 +20248,7 @@ var init_three_core = __esm({
|
|
|
20247
20248
|
phiLength
|
|
20248
20249
|
};
|
|
20249
20250
|
segments = Math.floor(segments);
|
|
20250
|
-
phiLength =
|
|
20251
|
+
phiLength = clamp2(phiLength, 0, Math.PI * 2);
|
|
20251
20252
|
const indices = [];
|
|
20252
20253
|
const vertices = [];
|
|
20253
20254
|
const uvs = [];
|
|
@@ -21463,7 +21464,7 @@ var init_three_core = __esm({
|
|
|
21463
21464
|
this.ior = 1.5;
|
|
21464
21465
|
Object.defineProperty(this, "reflectivity", {
|
|
21465
21466
|
get: function() {
|
|
21466
|
-
return
|
|
21467
|
+
return clamp2(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
|
|
21467
21468
|
},
|
|
21468
21469
|
set: function(reflectivity) {
|
|
21469
21470
|
this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
|
|
@@ -29731,7 +29732,7 @@ var init_three_core = __esm({
|
|
|
29731
29732
|
*/
|
|
29732
29733
|
makeSafe() {
|
|
29733
29734
|
const EPS = 1e-6;
|
|
29734
|
-
this.phi =
|
|
29735
|
+
this.phi = clamp2(this.phi, EPS, Math.PI - EPS);
|
|
29735
29736
|
return this;
|
|
29736
29737
|
}
|
|
29737
29738
|
/**
|
|
@@ -29759,7 +29760,7 @@ var init_three_core = __esm({
|
|
|
29759
29760
|
this.phi = 0;
|
|
29760
29761
|
} else {
|
|
29761
29762
|
this.theta = Math.atan2(x2, z);
|
|
29762
|
-
this.phi = Math.acos(
|
|
29763
|
+
this.phi = Math.acos(clamp2(y / this.radius, -1, 1));
|
|
29763
29764
|
}
|
|
29764
29765
|
return this;
|
|
29765
29766
|
}
|
|
@@ -30274,7 +30275,7 @@ var init_three_core = __esm({
|
|
|
30274
30275
|
const startEnd_startP = _startEnd.dot(_startP);
|
|
30275
30276
|
let t2 = startEnd_startP / startEnd2;
|
|
30276
30277
|
if (clampToLine) {
|
|
30277
|
-
t2 =
|
|
30278
|
+
t2 = clamp2(t2, 0, 1);
|
|
30278
30279
|
}
|
|
30279
30280
|
return t2;
|
|
30280
30281
|
}
|
|
@@ -30320,27 +30321,27 @@ var init_three_core = __esm({
|
|
|
30320
30321
|
if (a2 <= EPSILON) {
|
|
30321
30322
|
s = 0;
|
|
30322
30323
|
t2 = f / e2;
|
|
30323
|
-
t2 =
|
|
30324
|
+
t2 = clamp2(t2, 0, 1);
|
|
30324
30325
|
} else {
|
|
30325
30326
|
const c3 = _d1.dot(_r);
|
|
30326
30327
|
if (e2 <= EPSILON) {
|
|
30327
30328
|
t2 = 0;
|
|
30328
|
-
s =
|
|
30329
|
+
s = clamp2(-c3 / a2, 0, 1);
|
|
30329
30330
|
} else {
|
|
30330
30331
|
const b2 = _d1.dot(_d2);
|
|
30331
30332
|
const denom = a2 * e2 - b2 * b2;
|
|
30332
30333
|
if (denom !== 0) {
|
|
30333
|
-
s =
|
|
30334
|
+
s = clamp2((b2 * f - c3 * e2) / denom, 0, 1);
|
|
30334
30335
|
} else {
|
|
30335
30336
|
s = 0;
|
|
30336
30337
|
}
|
|
30337
30338
|
t2 = (b2 * s + f) / e2;
|
|
30338
30339
|
if (t2 < 0) {
|
|
30339
30340
|
t2 = 0;
|
|
30340
|
-
s =
|
|
30341
|
+
s = clamp2(-c3 / a2, 0, 1);
|
|
30341
30342
|
} else if (t2 > 1) {
|
|
30342
30343
|
t2 = 1;
|
|
30343
|
-
s =
|
|
30344
|
+
s = clamp2((b2 - c3) / a2, 0, 1);
|
|
30344
30345
|
}
|
|
30345
30346
|
}
|
|
30346
30347
|
}
|
|
@@ -43570,7 +43571,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43570
43571
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43571
43572
|
}
|
|
43572
43573
|
function useSyncExternalStore$2(subscribe3, getSnapshot2) {
|
|
43573
|
-
didWarnOld18Alpha || void 0 ===
|
|
43574
|
+
didWarnOld18Alpha || void 0 === React100.startTransition || (didWarnOld18Alpha = true, console.error(
|
|
43574
43575
|
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
43575
43576
|
));
|
|
43576
43577
|
var value = getSnapshot2();
|
|
@@ -43580,7 +43581,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43580
43581
|
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
43581
43582
|
), didWarnUncachedGetSnapshot = true);
|
|
43582
43583
|
}
|
|
43583
|
-
cachedValue =
|
|
43584
|
+
cachedValue = useState86({
|
|
43584
43585
|
inst: { value, getSnapshot: getSnapshot2 }
|
|
43585
43586
|
});
|
|
43586
43587
|
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
|
|
@@ -43618,8 +43619,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43618
43619
|
return getSnapshot2();
|
|
43619
43620
|
}
|
|
43620
43621
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43621
|
-
var
|
|
43622
|
-
exports$1.useSyncExternalStore = void 0 !==
|
|
43622
|
+
var React100 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is2, useState86 = React100.useState, useEffect72 = React100.useEffect, useLayoutEffect7 = React100.useLayoutEffect, useDebugValue = React100.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
43623
|
+
exports$1.useSyncExternalStore = void 0 !== React100.useSyncExternalStore ? React100.useSyncExternalStore : shim;
|
|
43623
43624
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
43624
43625
|
})();
|
|
43625
43626
|
}
|
|
@@ -43642,7 +43643,7 @@ var require_with_selector_development = __commonJS({
|
|
|
43642
43643
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43643
43644
|
}
|
|
43644
43645
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43645
|
-
var
|
|
43646
|
+
var React100 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef73 = React100.useRef, useEffect72 = React100.useEffect, useMemo41 = React100.useMemo, useDebugValue = React100.useDebugValue;
|
|
43646
43647
|
exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
|
|
43647
43648
|
var instRef = useRef73(null);
|
|
43648
43649
|
if (null === instRef.current) {
|
|
@@ -70290,6 +70291,55 @@ var ACTION_BUTTON_PRESETS = [
|
|
|
70290
70291
|
label: "Return",
|
|
70291
70292
|
defaultAction: "prevSlide",
|
|
70292
70293
|
iconPath: "M18 8 L18 14 L6 14 M6 14 L10 10 M6 14 L10 18"
|
|
70294
|
+
},
|
|
70295
|
+
{
|
|
70296
|
+
shapeType: "actionButtonHome",
|
|
70297
|
+
label: "Home",
|
|
70298
|
+
defaultAction: "firstSlide",
|
|
70299
|
+
// House: roof + body
|
|
70300
|
+
iconPath: "M12 4 L20 11 L20 20 L14 20 L14 14 L10 14 L10 20 L4 20 L4 11 Z"
|
|
70301
|
+
},
|
|
70302
|
+
{
|
|
70303
|
+
shapeType: "actionButtonHelp",
|
|
70304
|
+
label: "Help",
|
|
70305
|
+
defaultAction: "none",
|
|
70306
|
+
// Question mark
|
|
70307
|
+
iconPath: "M9 9 a3 3 0 1 1 4 2.8 c-1 0.4 -1 1.2 -1 2 M12 17 v0.5"
|
|
70308
|
+
},
|
|
70309
|
+
{
|
|
70310
|
+
shapeType: "actionButtonInformation",
|
|
70311
|
+
label: "Information",
|
|
70312
|
+
defaultAction: "none",
|
|
70313
|
+
// Lower-case "i": dot + body
|
|
70314
|
+
iconPath: "M12 6 v0.01 M12 10 v8"
|
|
70315
|
+
},
|
|
70316
|
+
{
|
|
70317
|
+
shapeType: "actionButtonDocument",
|
|
70318
|
+
label: "Document",
|
|
70319
|
+
defaultAction: "none",
|
|
70320
|
+
// Document with folded corner
|
|
70321
|
+
iconPath: "M6 4 L14 4 L18 8 L18 20 L6 20 Z M14 4 L14 8 L18 8"
|
|
70322
|
+
},
|
|
70323
|
+
{
|
|
70324
|
+
shapeType: "actionButtonSound",
|
|
70325
|
+
label: "Sound",
|
|
70326
|
+
defaultAction: "none",
|
|
70327
|
+
// Speaker cone + sound waves
|
|
70328
|
+
iconPath: "M4 10 L4 14 L8 14 L12 18 L12 6 L8 10 Z M16 9 a4 4 0 0 1 0 6 M18 7 a7 7 0 0 1 0 10"
|
|
70329
|
+
},
|
|
70330
|
+
{
|
|
70331
|
+
shapeType: "actionButtonMovie",
|
|
70332
|
+
label: "Movie",
|
|
70333
|
+
defaultAction: "none",
|
|
70334
|
+
// Film strip with play triangle
|
|
70335
|
+
iconPath: "M4 6 L20 6 L20 18 L4 18 Z M10 9 L15 12 L10 15 Z"
|
|
70336
|
+
},
|
|
70337
|
+
{
|
|
70338
|
+
shapeType: "actionButtonBlank",
|
|
70339
|
+
label: "Custom",
|
|
70340
|
+
defaultAction: "none",
|
|
70341
|
+
// No glyph — empty path. The button still renders as a rounded rect via clip-path.
|
|
70342
|
+
iconPath: ""
|
|
70293
70343
|
}
|
|
70294
70344
|
];
|
|
70295
70345
|
Object.fromEntries(ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.defaultAction]));
|
|
@@ -72569,8 +72619,8 @@ function hexToRgb2(hex) {
|
|
|
72569
72619
|
};
|
|
72570
72620
|
}
|
|
72571
72621
|
function rgbToHex(r2, g2, b2) {
|
|
72572
|
-
const
|
|
72573
|
-
return `#${
|
|
72622
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
72623
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
|
|
72574
72624
|
}
|
|
72575
72625
|
function rgbToHsl(r2, g2, b2) {
|
|
72576
72626
|
const rn = r2 / 255;
|
|
@@ -74074,6 +74124,13 @@ function hasDistinctScriptFonts(fonts) {
|
|
|
74074
74124
|
}
|
|
74075
74125
|
return Boolean(fonts.eastAsia) && fonts.eastAsia !== base || Boolean(fonts.complexScript) && fonts.complexScript !== base || Boolean(fonts.symbol) && fonts.symbol !== base;
|
|
74076
74126
|
}
|
|
74127
|
+
function sanitizeMathMl(markup) {
|
|
74128
|
+
const purify = DOMPurify;
|
|
74129
|
+
if (typeof purify.sanitize !== "function") {
|
|
74130
|
+
return markup;
|
|
74131
|
+
}
|
|
74132
|
+
return purify.sanitize(markup, { USE_PROFILES: { mathMl: true, svg: true } });
|
|
74133
|
+
}
|
|
74077
74134
|
function renderScriptAwareText(text2, needsScriptFonts, scriptFonts, baseFontFamily, keyPrefix) {
|
|
74078
74135
|
if (!needsScriptFonts || !text2) {
|
|
74079
74136
|
return text2;
|
|
@@ -74164,14 +74221,15 @@ function renderSegmentContent(elementId, segmentIndex, textValue, lines, needsSc
|
|
|
74164
74221
|
}
|
|
74165
74222
|
function renderEquationSegment(elementId, segmentIndex, equationXml, equationNumber) {
|
|
74166
74223
|
const mathml = convertOmmlToMathMl(equationXml);
|
|
74167
|
-
const
|
|
74224
|
+
const safeMathml = mathml ? sanitizeMathMl(mathml) : "";
|
|
74225
|
+
const equationContent = safeMathml ? /* @__PURE__ */ jsx(
|
|
74168
74226
|
"span",
|
|
74169
74227
|
{
|
|
74170
74228
|
className: "inline-block align-middle",
|
|
74171
74229
|
style: {
|
|
74172
74230
|
fontFamily: '"Cambria Math", "STIX Two Math", serif'
|
|
74173
74231
|
},
|
|
74174
|
-
dangerouslySetInnerHTML: { __html:
|
|
74232
|
+
dangerouslySetInnerHTML: { __html: safeMathml }
|
|
74175
74233
|
}
|
|
74176
74234
|
) : /* @__PURE__ */ jsx("span", { className: "inline-block px-1 py-0.5 rounded text-xs bg-gray-200/20 text-gray-400 italic", children: "Equation" });
|
|
74177
74235
|
if (equationNumber) {
|
|
@@ -74772,6 +74830,11 @@ function getShapeClipPath(shapeType, adjustments, width, height) {
|
|
|
74772
74830
|
}
|
|
74773
74831
|
const normalized = shapeType.toLowerCase();
|
|
74774
74832
|
if (normalized === "round1rect" || normalized === "round2samerect" || normalized === "round2diagrect" || normalized === "sniproundrect" || normalized === "snip1rect" || normalized === "snip2diagrect") {
|
|
74833
|
+
if (adjustments?.adj !== void 0 && width && height) {
|
|
74834
|
+
const ratio = Math.min(Math.max(adjustments.adj / 1e5, 0), 0.5);
|
|
74835
|
+
const radiusPx = Math.round(Math.min(width, height) * ratio);
|
|
74836
|
+
return `inset(0 round ${radiusPx}px)`;
|
|
74837
|
+
}
|
|
74775
74838
|
return "inset(0 round 18px)";
|
|
74776
74839
|
}
|
|
74777
74840
|
if (normalized === "can" || normalized === "cylinder") {
|
|
@@ -75418,6 +75481,128 @@ function mapDagBlendModeToCss(blend) {
|
|
|
75418
75481
|
return void 0;
|
|
75419
75482
|
}
|
|
75420
75483
|
}
|
|
75484
|
+
function getImageAlphaFilterId(elementId) {
|
|
75485
|
+
return `imgalpha-${elementId}`;
|
|
75486
|
+
}
|
|
75487
|
+
function hasAdvancedImageAlphaEffects(element2) {
|
|
75488
|
+
if (!isImageLikeElement(element2)) {
|
|
75489
|
+
return false;
|
|
75490
|
+
}
|
|
75491
|
+
const e2 = element2.imageEffects;
|
|
75492
|
+
if (!e2) {
|
|
75493
|
+
return false;
|
|
75494
|
+
}
|
|
75495
|
+
return Boolean(
|
|
75496
|
+
typeof e2.alphaModFix === "number" || e2.alphaInv || e2.alphaCeiling || e2.alphaFloor || typeof e2.alphaRepl === "number" || typeof e2.alphaBiLevel === "number" || typeof e2.biLevel === "number" || e2.lum && (typeof e2.lum.bright === "number" || typeof e2.lum.contrast === "number") || e2.hsl && (typeof e2.hsl.sat === "number" || typeof e2.hsl.lum === "number") || e2.tint && typeof e2.tint.amt === "number" || e2.clrRepl
|
|
75497
|
+
);
|
|
75498
|
+
}
|
|
75499
|
+
function renderImageAlphaSvgFilter(element2) {
|
|
75500
|
+
if (!isImageLikeElement(element2)) {
|
|
75501
|
+
return null;
|
|
75502
|
+
}
|
|
75503
|
+
const e2 = element2.imageEffects;
|
|
75504
|
+
if (!e2 || !hasAdvancedImageAlphaEffects(element2)) {
|
|
75505
|
+
return null;
|
|
75506
|
+
}
|
|
75507
|
+
const filterId = getImageAlphaFilterId(element2.id);
|
|
75508
|
+
const primitives = [];
|
|
75509
|
+
let resultIdx = 0;
|
|
75510
|
+
let inputRef = "SourceGraphic";
|
|
75511
|
+
const next = (jsx229) => {
|
|
75512
|
+
const result = `r${resultIdx++}`;
|
|
75513
|
+
primitives.push(jsx229(inputRef, result));
|
|
75514
|
+
inputRef = result;
|
|
75515
|
+
};
|
|
75516
|
+
if (typeof e2.alphaModFix === "number") {
|
|
75517
|
+
const mul = clamp(e2.alphaModFix / 100, 0, 1);
|
|
75518
|
+
next((inp, out) => /* @__PURE__ */ jsx(
|
|
75519
|
+
"feColorMatrix",
|
|
75520
|
+
{
|
|
75521
|
+
in: inp,
|
|
75522
|
+
result: out,
|
|
75523
|
+
type: "matrix",
|
|
75524
|
+
values: `1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ${mul} 0`
|
|
75525
|
+
},
|
|
75526
|
+
out
|
|
75527
|
+
));
|
|
75528
|
+
}
|
|
75529
|
+
if (e2.alphaInv) {
|
|
75530
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "linear", slope: -1, intercept: 1 }) }, out));
|
|
75531
|
+
}
|
|
75532
|
+
if (e2.alphaCeiling) {
|
|
75533
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: "0 1 1 1 1 1 1 1 1 1" }) }, out));
|
|
75534
|
+
}
|
|
75535
|
+
if (e2.alphaFloor) {
|
|
75536
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: "0 0 0 0 0 0 0 0 0 1" }) }, out));
|
|
75537
|
+
}
|
|
75538
|
+
if (typeof e2.alphaRepl === "number") {
|
|
75539
|
+
const a2 = clamp(e2.alphaRepl / 100, 0, 1);
|
|
75540
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "linear", slope: 0, intercept: a2 }) }, out));
|
|
75541
|
+
}
|
|
75542
|
+
if (typeof e2.alphaBiLevel === "number") {
|
|
75543
|
+
const t2 = clamp(e2.alphaBiLevel / 100, 0, 1);
|
|
75544
|
+
const table = Array.from({ length: 10 }, (_, i3) => i3 / 10 >= t2 ? "1" : "0").join(" ");
|
|
75545
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: table }) }, out));
|
|
75546
|
+
}
|
|
75547
|
+
if (typeof e2.biLevel === "number") {
|
|
75548
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: "0" }, out));
|
|
75549
|
+
const t2 = clamp(e2.biLevel / 100, 0, 1);
|
|
75550
|
+
const tbl = t2 < 0.5 ? "0 1" : "0 1";
|
|
75551
|
+
next((inp, out) => /* @__PURE__ */ jsxs("feComponentTransfer", { in: inp, result: out, children: [
|
|
75552
|
+
/* @__PURE__ */ jsx("feFuncR", { type: "discrete", tableValues: tbl }),
|
|
75553
|
+
/* @__PURE__ */ jsx("feFuncG", { type: "discrete", tableValues: tbl }),
|
|
75554
|
+
/* @__PURE__ */ jsx("feFuncB", { type: "discrete", tableValues: tbl })
|
|
75555
|
+
] }, out));
|
|
75556
|
+
}
|
|
75557
|
+
if (e2.lum && (typeof e2.lum.bright === "number" || typeof e2.lum.contrast === "number")) {
|
|
75558
|
+
const b2 = (e2.lum.bright ?? 0) / 100;
|
|
75559
|
+
const c2 = 1 + (e2.lum.contrast ?? 0) / 100;
|
|
75560
|
+
const slope = c2;
|
|
75561
|
+
const intercept = b2 + (1 - c2) / 2;
|
|
75562
|
+
next((inp, out) => /* @__PURE__ */ jsxs("feComponentTransfer", { in: inp, result: out, children: [
|
|
75563
|
+
/* @__PURE__ */ jsx("feFuncR", { type: "linear", slope, intercept }),
|
|
75564
|
+
/* @__PURE__ */ jsx("feFuncG", { type: "linear", slope, intercept }),
|
|
75565
|
+
/* @__PURE__ */ jsx("feFuncB", { type: "linear", slope, intercept })
|
|
75566
|
+
] }, out));
|
|
75567
|
+
}
|
|
75568
|
+
if (e2.hsl && typeof e2.hsl.sat === "number") {
|
|
75569
|
+
const v = clamp(1 + e2.hsl.sat / 100, 0, 2);
|
|
75570
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
|
|
75571
|
+
}
|
|
75572
|
+
if (e2.tint && typeof e2.tint.amt === "number" && e2.tint.amt < 0) {
|
|
75573
|
+
const v = clamp(1 + e2.tint.amt / 100, 0, 1);
|
|
75574
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
|
|
75575
|
+
}
|
|
75576
|
+
if (e2.clrRepl) {
|
|
75577
|
+
const c2 = hexToRgbUnit(e2.clrRepl.color);
|
|
75578
|
+
next((inp, out) => /* @__PURE__ */ jsx(
|
|
75579
|
+
"feColorMatrix",
|
|
75580
|
+
{
|
|
75581
|
+
in: inp,
|
|
75582
|
+
result: out,
|
|
75583
|
+
type: "matrix",
|
|
75584
|
+
values: `0 0 0 0 ${c2.r} 0 0 0 0 ${c2.g} 0 0 0 0 ${c2.b} 0 0 0 1 0`
|
|
75585
|
+
},
|
|
75586
|
+
out
|
|
75587
|
+
));
|
|
75588
|
+
}
|
|
75589
|
+
if (primitives.length === 0) {
|
|
75590
|
+
return null;
|
|
75591
|
+
}
|
|
75592
|
+
return /* @__PURE__ */ jsx(
|
|
75593
|
+
"svg",
|
|
75594
|
+
{
|
|
75595
|
+
width: 0,
|
|
75596
|
+
height: 0,
|
|
75597
|
+
style: { position: "absolute", overflow: "hidden" },
|
|
75598
|
+
"aria-hidden": "true",
|
|
75599
|
+
children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("filter", { id: filterId, colorInterpolationFilters: "sRGB", children: primitives }) })
|
|
75600
|
+
}
|
|
75601
|
+
);
|
|
75602
|
+
}
|
|
75603
|
+
function clamp(v, lo, hi) {
|
|
75604
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
75605
|
+
}
|
|
75421
75606
|
function getDagDuotoneFilterId(elementId) {
|
|
75422
75607
|
return `dag-duotone-${elementId}`;
|
|
75423
75608
|
}
|
|
@@ -75501,6 +75686,9 @@ function getImageEffectsFilter(element2, options) {
|
|
|
75501
75686
|
const filterId = getDuotoneFilterId(element2.id);
|
|
75502
75687
|
filters.push(`url(#${filterId})`);
|
|
75503
75688
|
}
|
|
75689
|
+
if (hasAdvancedImageAlphaEffects(element2)) {
|
|
75690
|
+
filters.push(`url(#${getImageAlphaFilterId(element2.id)})`);
|
|
75691
|
+
}
|
|
75504
75692
|
if (effects.artisticEffect) {
|
|
75505
75693
|
const radius = effects.artisticRadius ?? 5;
|
|
75506
75694
|
if (needsSvgArtisticFilter(effects.artisticEffect)) {
|
|
@@ -75674,6 +75862,39 @@ function getEffectDagCssFilter(style, elementId) {
|
|
|
75674
75862
|
return filters.length > 0 ? filters.join(" ") : void 0;
|
|
75675
75863
|
}
|
|
75676
75864
|
var getEffectDagFilter = getEffectDagCssFilter;
|
|
75865
|
+
function getResolvedShapeClipPathFor(shapeType, width, height, adjustments) {
|
|
75866
|
+
if (!shapeType) {
|
|
75867
|
+
return void 0;
|
|
75868
|
+
}
|
|
75869
|
+
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
|
|
75870
|
+
return getShapeClipPath(shapeType, adjustments, width, height);
|
|
75871
|
+
}
|
|
75872
|
+
if (adjustments && Object.keys(adjustments).length > 0) {
|
|
75873
|
+
const adjusted = getAdjustmentAwareShapeClipPath(shapeType, width, height, adjustments);
|
|
75874
|
+
if (adjusted !== void 0) {
|
|
75875
|
+
return adjusted;
|
|
75876
|
+
}
|
|
75877
|
+
}
|
|
75878
|
+
const fromPreset = getShapeClipPathFromPreset(shapeType, width, height, adjustments);
|
|
75879
|
+
if (fromPreset !== void 0) {
|
|
75880
|
+
return fromPreset;
|
|
75881
|
+
}
|
|
75882
|
+
const cloud = getCloudPathForRendering(shapeType, width, height);
|
|
75883
|
+
if (cloud !== void 0) {
|
|
75884
|
+
return cloud;
|
|
75885
|
+
}
|
|
75886
|
+
return getShapeClipPath(shapeType, adjustments, width, height);
|
|
75887
|
+
}
|
|
75888
|
+
function getResolvedShapeClipPath(element2, width, height) {
|
|
75889
|
+
const shapeType = element2.shapeType;
|
|
75890
|
+
if (!shapeType) {
|
|
75891
|
+
return void 0;
|
|
75892
|
+
}
|
|
75893
|
+
const w = element2.width;
|
|
75894
|
+
const h2 = element2.height;
|
|
75895
|
+
const adjustments = element2.shapeAdjustments;
|
|
75896
|
+
return getResolvedShapeClipPathFor(shapeType, w, h2, adjustments);
|
|
75897
|
+
}
|
|
75677
75898
|
|
|
75678
75899
|
// src/viewer/utils/shape-round-rect.ts
|
|
75679
75900
|
function localClampAdjustment(value) {
|
|
@@ -75745,6 +75966,27 @@ var MATERIAL_MAP = {
|
|
|
75745
75966
|
filter: "brightness(1.1) contrast(0.85)",
|
|
75746
75967
|
// Translucent powder: slight translucent glow
|
|
75747
75968
|
backgroundImage: "radial-gradient(ellipse at 30% 30%, rgba(255,255,255,0.1) 0%, transparent 60%)"
|
|
75969
|
+
},
|
|
75970
|
+
// Legacy materials (PowerPoint 2007 / earlier). Render as muted variants
|
|
75971
|
+
// of the modern equivalents so legacy decks still resemble the originals.
|
|
75972
|
+
legacyMatte: {
|
|
75973
|
+
filter: "brightness(0.92) saturate(0.85)",
|
|
75974
|
+
backgroundImage: "linear-gradient(180deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.04) 100%)"
|
|
75975
|
+
},
|
|
75976
|
+
legacyPlastic: {
|
|
75977
|
+
filter: "brightness(1.02) contrast(1.03)",
|
|
75978
|
+
boxShadow: "inset -2px -2px 5px rgba(255,255,255,0.3)",
|
|
75979
|
+
backgroundImage: "radial-gradient(ellipse 35% 25% at 25% 20%, rgba(255,255,255,0.15) 0%, transparent 70%)"
|
|
75980
|
+
},
|
|
75981
|
+
legacyMetal: {
|
|
75982
|
+
filter: "brightness(1.05) contrast(1.1) saturate(1.1)",
|
|
75983
|
+
boxShadow: "inset -2px -2px 6px rgba(255,255,255,0.35), inset 1px 1px 3px rgba(255,255,255,0.15)",
|
|
75984
|
+
backgroundImage: "linear-gradient(135deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.06) 25%, transparent 50%, rgba(0,0,0,0.05) 80%)"
|
|
75985
|
+
},
|
|
75986
|
+
legacyWireframe: {
|
|
75987
|
+
filter: "brightness(1) contrast(1.4) saturate(0.6)",
|
|
75988
|
+
// Wireframe: high contrast outline-emphasising look
|
|
75989
|
+
boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.4)"
|
|
75748
75990
|
}
|
|
75749
75991
|
};
|
|
75750
75992
|
function getMaterialCssOverrides(material) {
|
|
@@ -76699,8 +76941,7 @@ function getShapeVisualStyle(element2, hasFill, fillColor, strokeWidth, strokeCo
|
|
|
76699
76941
|
return {};
|
|
76700
76942
|
}
|
|
76701
76943
|
const normalizedShapeType = getShapeType(element2.shapeType);
|
|
76702
|
-
const
|
|
76703
|
-
const clipPath = getShapeClipPath(shapeType);
|
|
76944
|
+
const clipPath = getResolvedShapeClipPath(element2);
|
|
76704
76945
|
const fillOpacity = element2.shapeStyle?.fillOpacity;
|
|
76705
76946
|
const strokeOpacity = element2.shapeStyle?.strokeOpacity;
|
|
76706
76947
|
const strokeDash = normalizeStrokeDashType(element2.shapeStyle?.strokeDash);
|
|
@@ -77302,7 +77543,7 @@ function getImageMaskStyle(element2) {
|
|
|
77302
77543
|
if (normalized === "can" || normalized === "cylinder") {
|
|
77303
77544
|
return { borderRadius: "48% / 12%" };
|
|
77304
77545
|
}
|
|
77305
|
-
const clipPath =
|
|
77546
|
+
const clipPath = getResolvedShapeClipPath(element2);
|
|
77306
77547
|
if (!clipPath) {
|
|
77307
77548
|
return void 0;
|
|
77308
77549
|
}
|
|
@@ -77965,8 +78206,8 @@ function hexToRgb3(hex) {
|
|
|
77965
78206
|
};
|
|
77966
78207
|
}
|
|
77967
78208
|
function rgbToHex2(r2, g2, b2) {
|
|
77968
|
-
const
|
|
77969
|
-
return `#${
|
|
78209
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
78210
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0").toUpperCase()}${clamp3(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp3(b2).toString(16).padStart(2, "0").toUpperCase()}`;
|
|
77970
78211
|
}
|
|
77971
78212
|
function tintColor(hex, tintFactor) {
|
|
77972
78213
|
const { r: r2, g: g2, b: b2 } = hexToRgb3(hex);
|
|
@@ -78897,13 +79138,13 @@ function cellStyleToCss(style) {
|
|
|
78897
79138
|
}
|
|
78898
79139
|
if (style.textDirection) {
|
|
78899
79140
|
switch (style.textDirection) {
|
|
78900
|
-
case "
|
|
79141
|
+
case "vert":
|
|
78901
79142
|
case "eaVert":
|
|
78902
79143
|
case "wordArtVert":
|
|
78903
79144
|
case "wordArtVertRtl":
|
|
78904
79145
|
css.writingMode = "vertical-rl";
|
|
78905
79146
|
break;
|
|
78906
|
-
case "
|
|
79147
|
+
case "vert270":
|
|
78907
79148
|
case "mongolianVert":
|
|
78908
79149
|
css.writingMode = "vertical-lr";
|
|
78909
79150
|
break;
|
|
@@ -79430,8 +79671,8 @@ function hexToRgb4(hex) {
|
|
|
79430
79671
|
];
|
|
79431
79672
|
}
|
|
79432
79673
|
function rgbToHex3(r2, g2, b2) {
|
|
79433
|
-
const
|
|
79434
|
-
return `#${
|
|
79674
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
79675
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
|
|
79435
79676
|
}
|
|
79436
79677
|
function tint(hex, amount) {
|
|
79437
79678
|
const [r2, g2, b2] = hexToRgb4(hex);
|
|
@@ -81349,7 +81590,7 @@ function resolveRegionCode(label) {
|
|
|
81349
81590
|
return REGION_ALIAS_MAP[normalized];
|
|
81350
81591
|
}
|
|
81351
81592
|
function lerpColor(a2, b2, t2) {
|
|
81352
|
-
const
|
|
81593
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
81353
81594
|
const parse = (hex) => {
|
|
81354
81595
|
const h2 = hex.replace("#", "");
|
|
81355
81596
|
return [
|
|
@@ -81360,9 +81601,9 @@ function lerpColor(a2, b2, t2) {
|
|
|
81360
81601
|
};
|
|
81361
81602
|
const [r1, g1, b1] = parse(a2);
|
|
81362
81603
|
const [r2, g2, b22] = parse(b2);
|
|
81363
|
-
const r3 =
|
|
81364
|
-
const g3 =
|
|
81365
|
-
const bl =
|
|
81604
|
+
const r3 = clamp3(r1 + (r2 - r1) * t2);
|
|
81605
|
+
const g3 = clamp3(g1 + (g2 - g1) * t2);
|
|
81606
|
+
const bl = clamp3(b1 + (b22 - b1) * t2);
|
|
81366
81607
|
return `#${r3.toString(16).padStart(2, "0")}${g3.toString(16).padStart(2, "0")}${bl.toString(16).padStart(2, "0")}`;
|
|
81367
81608
|
}
|
|
81368
81609
|
function sequentialColorScale(t2) {
|
|
@@ -86528,7 +86769,7 @@ function ResizeHandle({
|
|
|
86528
86769
|
}
|
|
86529
86770
|
);
|
|
86530
86771
|
}
|
|
86531
|
-
function
|
|
86772
|
+
function SlideThumbnailImpl({
|
|
86532
86773
|
slide,
|
|
86533
86774
|
templateElements,
|
|
86534
86775
|
canvasSize
|
|
@@ -86766,6 +87007,37 @@ function ThumbnailTable({
|
|
|
86766
87007
|
}
|
|
86767
87008
|
return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[10px] text-muted-foreground pointer-events-none", children: "Table" });
|
|
86768
87009
|
}
|
|
87010
|
+
function arePropsEqual(prev, next) {
|
|
87011
|
+
if (prev.slide.id !== next.slide.id) {
|
|
87012
|
+
return false;
|
|
87013
|
+
}
|
|
87014
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
87015
|
+
return false;
|
|
87016
|
+
}
|
|
87017
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
87018
|
+
return false;
|
|
87019
|
+
}
|
|
87020
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
87021
|
+
return false;
|
|
87022
|
+
}
|
|
87023
|
+
if (prev.slide.backgroundColor !== next.slide.backgroundColor) {
|
|
87024
|
+
return false;
|
|
87025
|
+
}
|
|
87026
|
+
if (prev.slide.backgroundImage !== next.slide.backgroundImage) {
|
|
87027
|
+
return false;
|
|
87028
|
+
}
|
|
87029
|
+
if (prev.slide.backgroundGradient !== next.slide.backgroundGradient) {
|
|
87030
|
+
return false;
|
|
87031
|
+
}
|
|
87032
|
+
if (prev.templateElements !== next.templateElements) {
|
|
87033
|
+
return false;
|
|
87034
|
+
}
|
|
87035
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
87036
|
+
return false;
|
|
87037
|
+
}
|
|
87038
|
+
return true;
|
|
87039
|
+
}
|
|
87040
|
+
var SlideThumbnail = React10__default.memo(SlideThumbnailImpl, arePropsEqual);
|
|
86769
87041
|
function ContextMenu({
|
|
86770
87042
|
contextMenuState,
|
|
86771
87043
|
mode,
|
|
@@ -88083,6 +88355,59 @@ function WarpedText({
|
|
|
88083
88355
|
}
|
|
88084
88356
|
);
|
|
88085
88357
|
}
|
|
88358
|
+
var GLYPH_BY_SHAPE = Object.fromEntries(
|
|
88359
|
+
ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.iconPath])
|
|
88360
|
+
);
|
|
88361
|
+
GLYPH_BY_SHAPE["actionButtonForwardOrNext"] = GLYPH_BY_SHAPE["actionButtonForwardNext"];
|
|
88362
|
+
GLYPH_BY_SHAPE["actionButtonBackOrPrevious"] = GLYPH_BY_SHAPE["actionButtonBackPrevious"];
|
|
88363
|
+
function isActionButtonShape(shapeType) {
|
|
88364
|
+
return Boolean(shapeType && shapeType in GLYPH_BY_SHAPE);
|
|
88365
|
+
}
|
|
88366
|
+
function getActionButtonGlyphPath(shapeType) {
|
|
88367
|
+
if (!shapeType) {
|
|
88368
|
+
return void 0;
|
|
88369
|
+
}
|
|
88370
|
+
const path = GLYPH_BY_SHAPE[shapeType];
|
|
88371
|
+
return path && path.length > 0 ? path : void 0;
|
|
88372
|
+
}
|
|
88373
|
+
function ActionButtonGlyphOverlay({
|
|
88374
|
+
element: element2,
|
|
88375
|
+
color
|
|
88376
|
+
}) {
|
|
88377
|
+
const shapeType = "shapeType" in element2 ? element2.shapeType : void 0;
|
|
88378
|
+
const path = getActionButtonGlyphPath(shapeType);
|
|
88379
|
+
if (!path) {
|
|
88380
|
+
return null;
|
|
88381
|
+
}
|
|
88382
|
+
const stroke = color ?? ("textStyle" in element2 && element2.textStyle?.color || "#ffffff");
|
|
88383
|
+
return /* @__PURE__ */ jsx(
|
|
88384
|
+
"svg",
|
|
88385
|
+
{
|
|
88386
|
+
viewBox: "0 0 24 24",
|
|
88387
|
+
width: "100%",
|
|
88388
|
+
height: "100%",
|
|
88389
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
88390
|
+
style: {
|
|
88391
|
+
position: "absolute",
|
|
88392
|
+
inset: 0,
|
|
88393
|
+
pointerEvents: "none",
|
|
88394
|
+
padding: "20%"
|
|
88395
|
+
},
|
|
88396
|
+
"aria-hidden": "true",
|
|
88397
|
+
children: /* @__PURE__ */ jsx(
|
|
88398
|
+
"path",
|
|
88399
|
+
{
|
|
88400
|
+
d: path,
|
|
88401
|
+
fill: "none",
|
|
88402
|
+
stroke,
|
|
88403
|
+
strokeWidth: 2,
|
|
88404
|
+
strokeLinecap: "round",
|
|
88405
|
+
strokeLinejoin: "round"
|
|
88406
|
+
}
|
|
88407
|
+
)
|
|
88408
|
+
}
|
|
88409
|
+
);
|
|
88410
|
+
}
|
|
88086
88411
|
function ColorChangedImage({
|
|
88087
88412
|
src,
|
|
88088
88413
|
clrChange,
|
|
@@ -88353,6 +88678,7 @@ function renderImg(el, style, filter, alt, opacity) {
|
|
|
88353
88678
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88354
88679
|
tileDuotoneColors && renderDuotoneSvgFilter(el.id, tileDuotoneColors.color1, tileDuotoneColors.color2),
|
|
88355
88680
|
renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
|
|
88681
|
+
renderImageAlphaSvgFilter(el),
|
|
88356
88682
|
/* @__PURE__ */ jsx(
|
|
88357
88683
|
"div",
|
|
88358
88684
|
{
|
|
@@ -88374,6 +88700,7 @@ function renderImg(el, style, filter, alt, opacity) {
|
|
|
88374
88700
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88375
88701
|
duotoneColors && !useDuotoneCanvas && renderDuotoneSvgFilter(el.id, duotoneColors.color1, duotoneColors.color2),
|
|
88376
88702
|
renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
|
|
88703
|
+
renderImageAlphaSvgFilter(el),
|
|
88377
88704
|
useDuotoneCanvas && duotoneColors ? /* @__PURE__ */ jsx(
|
|
88378
88705
|
DuotoneImage,
|
|
88379
88706
|
{
|
|
@@ -90499,7 +90826,7 @@ function BendingProcessRenderer({
|
|
|
90499
90826
|
}
|
|
90500
90827
|
);
|
|
90501
90828
|
}
|
|
90502
|
-
function
|
|
90829
|
+
function SmartArtRendererImpl({
|
|
90503
90830
|
element: element2,
|
|
90504
90831
|
className = ""
|
|
90505
90832
|
}) {
|
|
@@ -90610,6 +90937,30 @@ function renderLayout(layoutType, element2, nodes, palette, style) {
|
|
|
90610
90937
|
}
|
|
90611
90938
|
return /* @__PURE__ */ jsx(ListRenderer, { element: element2, nodes, palette, style });
|
|
90612
90939
|
}
|
|
90940
|
+
function arePropsEqual2(prev, next) {
|
|
90941
|
+
if (prev.className !== next.className) {
|
|
90942
|
+
return false;
|
|
90943
|
+
}
|
|
90944
|
+
if (prev.element.id !== next.element.id) {
|
|
90945
|
+
return false;
|
|
90946
|
+
}
|
|
90947
|
+
if (prev.element.type !== next.element.type) {
|
|
90948
|
+
return false;
|
|
90949
|
+
}
|
|
90950
|
+
if (prev.element.width !== next.element.width || prev.element.height !== next.element.height) {
|
|
90951
|
+
return false;
|
|
90952
|
+
}
|
|
90953
|
+
if (prev.element.x !== next.element.x || prev.element.y !== next.element.y) {
|
|
90954
|
+
return false;
|
|
90955
|
+
}
|
|
90956
|
+
const prevData = prev.element.type === "smartArt" ? prev.element.smartArtData : void 0;
|
|
90957
|
+
const nextData = next.element.type === "smartArt" ? next.element.smartArtData : void 0;
|
|
90958
|
+
if (prevData !== nextData) {
|
|
90959
|
+
return false;
|
|
90960
|
+
}
|
|
90961
|
+
return true;
|
|
90962
|
+
}
|
|
90963
|
+
var SmartArtRenderer = React10__default.memo(SmartArtRendererImpl, arePropsEqual2);
|
|
90613
90964
|
function ZoomElementRenderer({
|
|
90614
90965
|
element: element2,
|
|
90615
90966
|
slides,
|
|
@@ -90858,8 +91209,11 @@ function renderBody(el, isImg, isEditing, editText, spellCheck, txtSE, txtS, vec
|
|
|
90858
91209
|
...scene3dStyle.perspective ? { perspective: scene3dStyle.perspective } : {},
|
|
90859
91210
|
...scene3dStyle.transformStyle ? { transformStyle: scene3dStyle.transformStyle } : {}
|
|
90860
91211
|
} : void 0;
|
|
91212
|
+
const shapeTypeForGlyph = "shapeType" in el ? el.shapeType : void 0;
|
|
91213
|
+
const showActionButtonGlyph = isActionButtonShape(shapeTypeForGlyph);
|
|
90861
91214
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
90862
91215
|
vecShape,
|
|
91216
|
+
showActionButtonGlyph && /* @__PURE__ */ jsx(ActionButtonGlyphOverlay, { element: el }),
|
|
90863
91217
|
isTxtEl ? useSvgWarp ? /* @__PURE__ */ jsx(
|
|
90864
91218
|
"div",
|
|
90865
91219
|
{
|
|
@@ -93553,7 +93907,7 @@ function SectionBlock({
|
|
|
93553
93907
|
)
|
|
93554
93908
|
] });
|
|
93555
93909
|
}
|
|
93556
|
-
function
|
|
93910
|
+
function SlideCardImpl({
|
|
93557
93911
|
slide,
|
|
93558
93912
|
index,
|
|
93559
93913
|
isActive,
|
|
@@ -93607,6 +93961,49 @@ function SlideCard({
|
|
|
93607
93961
|
}
|
|
93608
93962
|
);
|
|
93609
93963
|
}
|
|
93964
|
+
function arePropsEqual3(prev, next) {
|
|
93965
|
+
if (prev.slide.id !== next.slide.id) {
|
|
93966
|
+
return false;
|
|
93967
|
+
}
|
|
93968
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
93969
|
+
return false;
|
|
93970
|
+
}
|
|
93971
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
93972
|
+
return false;
|
|
93973
|
+
}
|
|
93974
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
93975
|
+
return false;
|
|
93976
|
+
}
|
|
93977
|
+
if (prev.index !== next.index) {
|
|
93978
|
+
return false;
|
|
93979
|
+
}
|
|
93980
|
+
if (prev.isActive !== next.isActive) {
|
|
93981
|
+
return false;
|
|
93982
|
+
}
|
|
93983
|
+
if (prev.isDragTarget !== next.isDragTarget) {
|
|
93984
|
+
return false;
|
|
93985
|
+
}
|
|
93986
|
+
if (prev.isSelected !== next.isSelected) {
|
|
93987
|
+
return false;
|
|
93988
|
+
}
|
|
93989
|
+
if (prev.selectedCount !== next.selectedCount) {
|
|
93990
|
+
return false;
|
|
93991
|
+
}
|
|
93992
|
+
if (prev.selectionOrder !== next.selectionOrder) {
|
|
93993
|
+
return false;
|
|
93994
|
+
}
|
|
93995
|
+
if (prev.canEdit !== next.canEdit) {
|
|
93996
|
+
return false;
|
|
93997
|
+
}
|
|
93998
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
93999
|
+
return false;
|
|
94000
|
+
}
|
|
94001
|
+
if (prev.onSlideClick !== next.onSlideClick || prev.onDoubleClick !== next.onDoubleClick || prev.onContextMenu !== next.onContextMenu || prev.onDragStart !== next.onDragStart || prev.onDragOver !== next.onDragOver || prev.onDragLeave !== next.onDragLeave || prev.onDrop !== next.onDrop) {
|
|
94002
|
+
return false;
|
|
94003
|
+
}
|
|
94004
|
+
return true;
|
|
94005
|
+
}
|
|
94006
|
+
var SlideCard = React10__default.memo(SlideCardImpl, arePropsEqual3);
|
|
93610
94007
|
function SorterContextMenu({
|
|
93611
94008
|
x: x2,
|
|
93612
94009
|
y,
|
|
@@ -94400,6 +94797,14 @@ function getCurrentParagraphIndex(editorEl, segments) {
|
|
|
94400
94797
|
}
|
|
94401
94798
|
return paraIdx;
|
|
94402
94799
|
}
|
|
94800
|
+
var CSS_VALUE_SAFE = /^[a-zA-Z0-9 _,.\-+#'%/]{1,100}$/;
|
|
94801
|
+
function isCssValueSafe(value) {
|
|
94802
|
+
if (value === void 0 || value === null) {
|
|
94803
|
+
return false;
|
|
94804
|
+
}
|
|
94805
|
+
const str = String(value);
|
|
94806
|
+
return str.length > 0 && CSS_VALUE_SAFE.test(str);
|
|
94807
|
+
}
|
|
94403
94808
|
function deriveStyleFromElement(element2, inheritedStyle) {
|
|
94404
94809
|
const style = { ...inheritedStyle };
|
|
94405
94810
|
const tagName = element2.tagName.toLowerCase();
|
|
@@ -94532,17 +94937,17 @@ function segmentsToEditorHtml(segments) {
|
|
|
94532
94937
|
if (segment.style.strikethrough) {
|
|
94533
94938
|
inlineStyles.push("text-decoration:line-through");
|
|
94534
94939
|
}
|
|
94535
|
-
if (segment.style.color) {
|
|
94940
|
+
if (segment.style.color && isCssValueSafe(segment.style.color)) {
|
|
94536
94941
|
inlineStyles.push(`color:${segment.style.color}`);
|
|
94537
94942
|
}
|
|
94538
|
-
if (segment.style.fontSize) {
|
|
94539
|
-
inlineStyles.push(`font-size:${segment.style.fontSize}pt`);
|
|
94943
|
+
if (segment.style.fontSize && Number.isFinite(Number(segment.style.fontSize))) {
|
|
94944
|
+
inlineStyles.push(`font-size:${Number(segment.style.fontSize)}pt`);
|
|
94540
94945
|
}
|
|
94541
|
-
if (segment.style.fontFamily) {
|
|
94946
|
+
if (segment.style.fontFamily && isCssValueSafe(segment.style.fontFamily)) {
|
|
94542
94947
|
inlineStyles.push(`font-family:${segment.style.fontFamily}`);
|
|
94543
94948
|
}
|
|
94544
94949
|
const text2 = escapeHtml(segment.text);
|
|
94545
|
-
if (segment.style.hyperlink) {
|
|
94950
|
+
if (segment.style.hyperlink && isUrlSafe(segment.style.hyperlink)) {
|
|
94546
94951
|
const href = escapeHtml(segment.style.hyperlink);
|
|
94547
94952
|
return `<a href="${href}" style="color:#4a9eff;text-decoration:underline;cursor:pointer" data-hyperlink="${href}">${text2}</a>`;
|
|
94548
94953
|
}
|
|
@@ -94625,7 +95030,8 @@ function renderRichNotesSegments(segments) {
|
|
|
94625
95030
|
if (segment.style.fontFamily) {
|
|
94626
95031
|
style.fontFamily = segment.style.fontFamily;
|
|
94627
95032
|
}
|
|
94628
|
-
if (segment.style.hyperlink) {
|
|
95033
|
+
if (segment.style.hyperlink && isUrlSafe(segment.style.hyperlink)) {
|
|
95034
|
+
const safeHref = segment.style.hyperlink;
|
|
94629
95035
|
style.color = "#4a9eff";
|
|
94630
95036
|
style.textDecoration = "underline";
|
|
94631
95037
|
style.cursor = "pointer";
|
|
@@ -94633,11 +95039,11 @@ function renderRichNotesSegments(segments) {
|
|
|
94633
95039
|
/* @__PURE__ */ jsx(
|
|
94634
95040
|
"a",
|
|
94635
95041
|
{
|
|
94636
|
-
href:
|
|
95042
|
+
href: safeHref,
|
|
94637
95043
|
style,
|
|
94638
95044
|
onClick: (e2) => {
|
|
94639
95045
|
e2.preventDefault();
|
|
94640
|
-
|
|
95046
|
+
safeOpenUrl(safeHref);
|
|
94641
95047
|
},
|
|
94642
95048
|
children: segment.text
|
|
94643
95049
|
},
|
|
@@ -95189,7 +95595,7 @@ function useSlideNotes({
|
|
|
95189
95595
|
const href = target.getAttribute("data-hyperlink") || target.getAttribute("href");
|
|
95190
95596
|
if (href && (e2.ctrlKey || e2.metaKey)) {
|
|
95191
95597
|
e2.preventDefault();
|
|
95192
|
-
|
|
95598
|
+
safeOpenUrl(href);
|
|
95193
95599
|
}
|
|
95194
95600
|
}, []);
|
|
95195
95601
|
return {
|
|
@@ -96862,7 +97268,7 @@ function renderNotesSegments(segments) {
|
|
|
96862
97268
|
return React10__default.createElement("span", { key: `seg-${index}`, style }, segment.text);
|
|
96863
97269
|
});
|
|
96864
97270
|
}
|
|
96865
|
-
function
|
|
97271
|
+
function ScaledSlidePreviewImpl({
|
|
96866
97272
|
slide,
|
|
96867
97273
|
templateElements,
|
|
96868
97274
|
canvasSize,
|
|
@@ -97009,6 +97415,40 @@ function ScaledSlidePreview({
|
|
|
97009
97415
|
}
|
|
97010
97416
|
);
|
|
97011
97417
|
}
|
|
97418
|
+
function arePropsEqual4(prev, next) {
|
|
97419
|
+
if (prev.slide.id !== next.slide.id) {
|
|
97420
|
+
return false;
|
|
97421
|
+
}
|
|
97422
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
97423
|
+
return false;
|
|
97424
|
+
}
|
|
97425
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
97426
|
+
return false;
|
|
97427
|
+
}
|
|
97428
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
97429
|
+
return false;
|
|
97430
|
+
}
|
|
97431
|
+
if (prev.slide.backgroundColor !== next.slide.backgroundColor) {
|
|
97432
|
+
return false;
|
|
97433
|
+
}
|
|
97434
|
+
if (prev.slide.backgroundImage !== next.slide.backgroundImage) {
|
|
97435
|
+
return false;
|
|
97436
|
+
}
|
|
97437
|
+
if (prev.slide.backgroundGradient !== next.slide.backgroundGradient) {
|
|
97438
|
+
return false;
|
|
97439
|
+
}
|
|
97440
|
+
if (prev.templateElements !== next.templateElements) {
|
|
97441
|
+
return false;
|
|
97442
|
+
}
|
|
97443
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
97444
|
+
return false;
|
|
97445
|
+
}
|
|
97446
|
+
if (prev.className !== next.className) {
|
|
97447
|
+
return false;
|
|
97448
|
+
}
|
|
97449
|
+
return true;
|
|
97450
|
+
}
|
|
97451
|
+
var ScaledSlidePreview = React10__default.memo(ScaledSlidePreviewImpl, arePropsEqual4);
|
|
97012
97452
|
function PresenterView({
|
|
97013
97453
|
slides,
|
|
97014
97454
|
currentSlideIndex,
|
|
@@ -111312,6 +111752,13 @@ function convertOmmlToLatex(omml) {
|
|
|
111312
111752
|
}
|
|
111313
111753
|
return ommlChildrenToLatex(oMath);
|
|
111314
111754
|
}
|
|
111755
|
+
function sanitizeMathMl2(markup) {
|
|
111756
|
+
const purify = DOMPurify;
|
|
111757
|
+
if (typeof purify.sanitize !== "function") {
|
|
111758
|
+
return markup;
|
|
111759
|
+
}
|
|
111760
|
+
return purify.sanitize(markup, { USE_PROFILES: { mathMl: true, svg: true } });
|
|
111761
|
+
}
|
|
111315
111762
|
var TEMPLATES = [
|
|
111316
111763
|
{
|
|
111317
111764
|
label: "Fraction",
|
|
@@ -111377,7 +111824,8 @@ var TEMPLATES = [
|
|
|
111377
111824
|
var TEMPLATE_MATHML = TEMPLATES.map((tmpl) => {
|
|
111378
111825
|
try {
|
|
111379
111826
|
const tmplOmml = convertLatexToOmml(tmpl.latex);
|
|
111380
|
-
|
|
111827
|
+
const raw = convertOmmlToMathMl(tmplOmml);
|
|
111828
|
+
return raw ? sanitizeMathMl2(raw) : "";
|
|
111381
111829
|
} catch {
|
|
111382
111830
|
return "";
|
|
111383
111831
|
}
|
|
@@ -111389,7 +111837,7 @@ function MathMlPreview({ mathml }) {
|
|
|
111389
111837
|
return;
|
|
111390
111838
|
}
|
|
111391
111839
|
if (mathml) {
|
|
111392
|
-
containerRef.current.innerHTML = mathml;
|
|
111840
|
+
containerRef.current.innerHTML = sanitizeMathMl2(mathml);
|
|
111393
111841
|
} else {
|
|
111394
111842
|
containerRef.current.innerHTML = "";
|
|
111395
111843
|
}
|
|
@@ -111417,6 +111865,7 @@ function EquationEditorDialog({
|
|
|
111417
111865
|
return convertOmmlToLatex(existingOmml);
|
|
111418
111866
|
}, [existingOmml]);
|
|
111419
111867
|
const [latex, setLatex] = useState(initialLatex);
|
|
111868
|
+
const deferredLatex = useDeferredValue(latex);
|
|
111420
111869
|
const textareaRef = useRef(null);
|
|
111421
111870
|
useEffect(() => {
|
|
111422
111871
|
if (isOpen) {
|
|
@@ -111425,17 +111874,17 @@ function EquationEditorDialog({
|
|
|
111425
111874
|
}
|
|
111426
111875
|
}, [isOpen, initialLatex]);
|
|
111427
111876
|
const { mathml, omml } = useMemo(() => {
|
|
111428
|
-
if (!
|
|
111877
|
+
if (!deferredLatex.trim()) {
|
|
111429
111878
|
return { mathml: "", omml: {} };
|
|
111430
111879
|
}
|
|
111431
111880
|
try {
|
|
111432
|
-
const ommlObj = convertLatexToOmml(
|
|
111881
|
+
const ommlObj = convertLatexToOmml(deferredLatex);
|
|
111433
111882
|
const mathmlStr = convertOmmlToMathMl(ommlObj);
|
|
111434
111883
|
return { mathml: mathmlStr, omml: ommlObj };
|
|
111435
111884
|
} catch {
|
|
111436
111885
|
return { mathml: "", omml: {} };
|
|
111437
111886
|
}
|
|
111438
|
-
}, [
|
|
111887
|
+
}, [deferredLatex]);
|
|
111439
111888
|
const handleInsert = useCallback(() => {
|
|
111440
111889
|
if (!latex.trim()) {
|
|
111441
111890
|
return;
|
|
@@ -114170,6 +114619,7 @@ function useEditorHistory(input) {
|
|
|
114170
114619
|
const historyFutureRef = useRef([]);
|
|
114171
114620
|
const lastHistorySnapshotRef = useRef(null);
|
|
114172
114621
|
const lastHistorySerializedRef = useRef("");
|
|
114622
|
+
const lastCheapHashRef = useRef("");
|
|
114173
114623
|
const isApplyingHistoryRef = useRef(false);
|
|
114174
114624
|
const unlockHistoryTimerRef = useRef(null);
|
|
114175
114625
|
const [canUndo, setCanUndo] = useState(false);
|
|
@@ -114311,15 +114761,21 @@ function useEditorHistory(input) {
|
|
|
114311
114761
|
if (hasActivePointerInteraction()) {
|
|
114312
114762
|
return;
|
|
114313
114763
|
}
|
|
114764
|
+
const cheapHash = `${slides.length}|${activeSlideIndex}|${canvasSize.width}x${canvasSize.height}|${slides.map((s) => `${s.id}:${s.elements.length}`).join("/")}`;
|
|
114765
|
+
if (cheapHash === lastCheapHashRef.current) {
|
|
114766
|
+
return;
|
|
114767
|
+
}
|
|
114314
114768
|
const snapshot2 = buildHistorySnapshot();
|
|
114315
114769
|
const serialized = JSON.stringify(snapshot2);
|
|
114316
114770
|
if (serialized === lastHistorySerializedRef.current) {
|
|
114771
|
+
lastCheapHashRef.current = cheapHash;
|
|
114317
114772
|
return;
|
|
114318
114773
|
}
|
|
114319
114774
|
const previousSnapshot = lastHistorySnapshotRef.current;
|
|
114320
114775
|
if (!previousSnapshot) {
|
|
114321
114776
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot2);
|
|
114322
114777
|
lastHistorySerializedRef.current = serialized;
|
|
114778
|
+
lastCheapHashRef.current = cheapHash;
|
|
114323
114779
|
updateHistoryAvailability();
|
|
114324
114780
|
return;
|
|
114325
114781
|
}
|
|
@@ -114330,13 +114786,18 @@ function useEditorHistory(input) {
|
|
|
114330
114786
|
historyFutureRef.current = [];
|
|
114331
114787
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot2);
|
|
114332
114788
|
lastHistorySerializedRef.current = serialized;
|
|
114789
|
+
lastCheapHashRef.current = cheapHash;
|
|
114333
114790
|
updateHistoryAvailability();
|
|
114334
114791
|
}, [
|
|
114792
|
+
activeSlideIndex,
|
|
114335
114793
|
buildHistorySnapshot,
|
|
114794
|
+
canvasSize.height,
|
|
114795
|
+
canvasSize.width,
|
|
114336
114796
|
error2,
|
|
114337
114797
|
hasActivePointerInteraction,
|
|
114338
114798
|
loading2,
|
|
114339
114799
|
pointerCommitNonce,
|
|
114800
|
+
slides,
|
|
114340
114801
|
updateHistoryAvailability
|
|
114341
114802
|
]);
|
|
114342
114803
|
return {
|
|
@@ -118048,7 +118509,8 @@ async function storeAudienceContent(content) {
|
|
|
118048
118509
|
const tx = db.transaction(STORE_NAME2, "readwrite");
|
|
118049
118510
|
const store = tx.objectStore(STORE_NAME2);
|
|
118050
118511
|
const bytes = content instanceof Uint8Array ? content : new Uint8Array(content);
|
|
118051
|
-
|
|
118512
|
+
const record = { bytes, createdAt: Date.now() };
|
|
118513
|
+
store.put(record, CONTENT_KEY);
|
|
118052
118514
|
tx.oncomplete = () => {
|
|
118053
118515
|
db.close();
|
|
118054
118516
|
resolve2();
|
|
@@ -118081,14 +118543,34 @@ async function clearAudienceContent() {
|
|
|
118081
118543
|
var PRESENTER_CHANNEL_NAME = "pptx-viewer-presenter";
|
|
118082
118544
|
var AUDIENCE_HASH = "#pptx-audience";
|
|
118083
118545
|
var PRESENTER_MSG_ORIGIN = "pptx-viewer-presenter";
|
|
118546
|
+
var AUDIENCE_NONCE_KEY = "nonce";
|
|
118547
|
+
function generateSessionId() {
|
|
118548
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
118549
|
+
return crypto.randomUUID();
|
|
118550
|
+
}
|
|
118551
|
+
return `s${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
118552
|
+
}
|
|
118553
|
+
function parseAudienceNonce() {
|
|
118554
|
+
const hash = window.location.hash;
|
|
118555
|
+
if (!hash.startsWith(AUDIENCE_HASH)) {
|
|
118556
|
+
return null;
|
|
118557
|
+
}
|
|
118558
|
+
const trailing = hash.slice(AUDIENCE_HASH.length);
|
|
118559
|
+
if (!trailing) {
|
|
118560
|
+
return null;
|
|
118561
|
+
}
|
|
118562
|
+
const params2 = new URLSearchParams(trailing.replace(/^[&;?]/, ""));
|
|
118563
|
+
return params2.get(AUDIENCE_NONCE_KEY);
|
|
118564
|
+
}
|
|
118084
118565
|
function isAudienceTab() {
|
|
118085
|
-
return window.location.hash
|
|
118566
|
+
return window.location.hash.startsWith(AUDIENCE_HASH);
|
|
118086
118567
|
}
|
|
118087
118568
|
function usePresenterWindow(input) {
|
|
118088
118569
|
const { currentSlideIndex, isPresenterMode, content } = input;
|
|
118089
118570
|
const audienceWindowRef = useRef(null);
|
|
118090
118571
|
const channelRef = useRef(null);
|
|
118091
118572
|
const pollTimerRef = useRef(null);
|
|
118573
|
+
const sessionIdRef = useRef("");
|
|
118092
118574
|
const getChannel2 = useCallback(() => {
|
|
118093
118575
|
if (!channelRef.current) {
|
|
118094
118576
|
channelRef.current = new BroadcastChannel(PRESENTER_CHANNEL_NAME);
|
|
@@ -118100,10 +118582,14 @@ function usePresenterWindow(input) {
|
|
|
118100
118582
|
}, []);
|
|
118101
118583
|
const syncSlideToAudience = useCallback(
|
|
118102
118584
|
(slideIndex) => {
|
|
118585
|
+
if (!sessionIdRef.current) {
|
|
118586
|
+
return;
|
|
118587
|
+
}
|
|
118103
118588
|
const msg = {
|
|
118104
118589
|
origin: PRESENTER_MSG_ORIGIN,
|
|
118105
118590
|
type: "presenter-slide-change",
|
|
118106
|
-
slideIndex
|
|
118591
|
+
slideIndex,
|
|
118592
|
+
sessionId: sessionIdRef.current
|
|
118107
118593
|
};
|
|
118108
118594
|
try {
|
|
118109
118595
|
getChannel2().postMessage(msg);
|
|
@@ -118113,13 +118599,16 @@ function usePresenterWindow(input) {
|
|
|
118113
118599
|
[getChannel2]
|
|
118114
118600
|
);
|
|
118115
118601
|
const closeAudienceWindow = useCallback(() => {
|
|
118116
|
-
|
|
118117
|
-
|
|
118118
|
-
|
|
118119
|
-
|
|
118120
|
-
|
|
118121
|
-
|
|
118122
|
-
|
|
118602
|
+
if (sessionIdRef.current) {
|
|
118603
|
+
try {
|
|
118604
|
+
const exitMsg = {
|
|
118605
|
+
origin: PRESENTER_MSG_ORIGIN,
|
|
118606
|
+
type: "presenter-exit",
|
|
118607
|
+
sessionId: sessionIdRef.current
|
|
118608
|
+
};
|
|
118609
|
+
getChannel2().postMessage(exitMsg);
|
|
118610
|
+
} catch {
|
|
118611
|
+
}
|
|
118123
118612
|
}
|
|
118124
118613
|
const win = audienceWindowRef.current;
|
|
118125
118614
|
if (win && !win.closed) {
|
|
@@ -118129,6 +118618,7 @@ function usePresenterWindow(input) {
|
|
|
118129
118618
|
}
|
|
118130
118619
|
}
|
|
118131
118620
|
audienceWindowRef.current = null;
|
|
118621
|
+
sessionIdRef.current = "";
|
|
118132
118622
|
if (pollTimerRef.current !== null) {
|
|
118133
118623
|
clearInterval(pollTimerRef.current);
|
|
118134
118624
|
pollTimerRef.current = null;
|
|
@@ -118139,20 +118629,53 @@ function usePresenterWindow(input) {
|
|
|
118139
118629
|
if (isAudienceWindowOpen()) {
|
|
118140
118630
|
closeAudienceWindow();
|
|
118141
118631
|
}
|
|
118142
|
-
|
|
118143
|
-
|
|
118144
|
-
}
|
|
118145
|
-
const url = new URL(window.location.href);
|
|
118146
|
-
url.hash = AUDIENCE_HASH;
|
|
118147
|
-
const win = window.open(url.toString(), "_blank");
|
|
118148
|
-
if (!win) {
|
|
118632
|
+
const blankWin = window.open("about:blank", "_blank");
|
|
118633
|
+
if (!blankWin) {
|
|
118149
118634
|
return false;
|
|
118150
118635
|
}
|
|
118151
|
-
audienceWindowRef.current =
|
|
118636
|
+
audienceWindowRef.current = blankWin;
|
|
118637
|
+
const sessionId = generateSessionId();
|
|
118638
|
+
sessionIdRef.current = sessionId;
|
|
118639
|
+
const audienceUrl = new URL(window.location.href);
|
|
118640
|
+
const params2 = new URLSearchParams();
|
|
118641
|
+
params2.set(AUDIENCE_NONCE_KEY, sessionId);
|
|
118642
|
+
audienceUrl.hash = `${AUDIENCE_HASH}&${params2.toString()}`;
|
|
118643
|
+
const navigateOrClose = (ok) => {
|
|
118644
|
+
const win = audienceWindowRef.current;
|
|
118645
|
+
if (!win || win.closed) {
|
|
118646
|
+
return;
|
|
118647
|
+
}
|
|
118648
|
+
if (!ok) {
|
|
118649
|
+
try {
|
|
118650
|
+
win.close();
|
|
118651
|
+
} catch {
|
|
118652
|
+
}
|
|
118653
|
+
audienceWindowRef.current = null;
|
|
118654
|
+
sessionIdRef.current = "";
|
|
118655
|
+
return;
|
|
118656
|
+
}
|
|
118657
|
+
try {
|
|
118658
|
+
win.location.replace(audienceUrl.toString());
|
|
118659
|
+
} catch {
|
|
118660
|
+
try {
|
|
118661
|
+
win.close();
|
|
118662
|
+
} catch {
|
|
118663
|
+
}
|
|
118664
|
+
audienceWindowRef.current = null;
|
|
118665
|
+
sessionIdRef.current = "";
|
|
118666
|
+
}
|
|
118667
|
+
};
|
|
118668
|
+
if (content) {
|
|
118669
|
+
void storeAudienceContent(content).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
|
|
118670
|
+
} else {
|
|
118671
|
+
navigateOrClose(true);
|
|
118672
|
+
}
|
|
118152
118673
|
window.setTimeout(() => syncSlideToAudience(currentSlideIndex), 1500);
|
|
118153
118674
|
pollTimerRef.current = setInterval(() => {
|
|
118154
|
-
|
|
118675
|
+
const win = audienceWindowRef.current;
|
|
118676
|
+
if (!win || win.closed) {
|
|
118155
118677
|
audienceWindowRef.current = null;
|
|
118678
|
+
sessionIdRef.current = "";
|
|
118156
118679
|
if (pollTimerRef.current !== null) {
|
|
118157
118680
|
clearInterval(pollTimerRef.current);
|
|
118158
118681
|
pollTimerRef.current = null;
|
|
@@ -118180,6 +118703,13 @@ function usePresenterWindow(input) {
|
|
|
118180
118703
|
closeAudienceWindow();
|
|
118181
118704
|
}
|
|
118182
118705
|
}, [isPresenterMode, closeAudienceWindow]);
|
|
118706
|
+
useEffect(() => {
|
|
118707
|
+
const handleBeforeUnload = () => {
|
|
118708
|
+
void clearAudienceContent();
|
|
118709
|
+
};
|
|
118710
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
118711
|
+
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
118712
|
+
}, []);
|
|
118183
118713
|
return {
|
|
118184
118714
|
openAudienceWindow,
|
|
118185
118715
|
closeAudienceWindow,
|
|
@@ -118217,6 +118747,7 @@ function useAudienceMode(input) {
|
|
|
118217
118747
|
if (!isAudienceTab()) {
|
|
118218
118748
|
return;
|
|
118219
118749
|
}
|
|
118750
|
+
const expectedSessionId = parseAudienceNonce();
|
|
118220
118751
|
let channel;
|
|
118221
118752
|
try {
|
|
118222
118753
|
channel = new BroadcastChannel(PRESENTER_CHANNEL_NAME);
|
|
@@ -118228,6 +118759,9 @@ function useAudienceMode(input) {
|
|
|
118228
118759
|
if (!data || data.origin !== PRESENTER_MSG_ORIGIN) {
|
|
118229
118760
|
return;
|
|
118230
118761
|
}
|
|
118762
|
+
if (expectedSessionId && data.sessionId !== expectedSessionId) {
|
|
118763
|
+
return;
|
|
118764
|
+
}
|
|
118231
118765
|
if (data.type === "presenter-slide-change") {
|
|
118232
118766
|
onSetActiveSlideIndex(data.slideIndex);
|
|
118233
118767
|
}
|
|
@@ -119161,6 +119695,12 @@ function useTouchGestures(input) {
|
|
|
119161
119695
|
callbacksRef.current = callbacks;
|
|
119162
119696
|
const scaleRef = useRef(currentScale);
|
|
119163
119697
|
scaleRef.current = currentScale;
|
|
119698
|
+
const [targetVersion, setTargetVersion] = useState(0);
|
|
119699
|
+
const lastTargetRef = useRef(null);
|
|
119700
|
+
if (targetRef.current !== lastTargetRef.current) {
|
|
119701
|
+
lastTargetRef.current = targetRef.current;
|
|
119702
|
+
queueMicrotask(() => setTargetVersion((v) => v + 1));
|
|
119703
|
+
}
|
|
119164
119704
|
useEffect(() => {
|
|
119165
119705
|
const el = targetRef.current;
|
|
119166
119706
|
if (!el || !enabled) {
|
|
@@ -119249,7 +119789,7 @@ function useTouchGestures(input) {
|
|
|
119249
119789
|
el.removeEventListener("touchcancel", handleTouchCancel);
|
|
119250
119790
|
cancelLongPress();
|
|
119251
119791
|
};
|
|
119252
|
-
}, [targetRef, enabled]);
|
|
119792
|
+
}, [targetRef, enabled, targetVersion]);
|
|
119253
119793
|
}
|
|
119254
119794
|
|
|
119255
119795
|
// src/viewer/utils/dom-helpers.ts
|
|
@@ -119270,11 +119810,31 @@ function safeConfirm(message) {
|
|
|
119270
119810
|
return false;
|
|
119271
119811
|
}
|
|
119272
119812
|
}
|
|
119813
|
+
function sanitizeDownloadFilename(input) {
|
|
119814
|
+
if (typeof input !== "string" || input.trim().length === 0) {
|
|
119815
|
+
return "presentation.pptx";
|
|
119816
|
+
}
|
|
119817
|
+
let cleaned = input.replace(/[\x00-\x1f\x7f"\\/:*?<>|]/g, "_").replace(/\.\./g, "__").replace(/^\.+/, "").trim();
|
|
119818
|
+
if (cleaned.length === 0) {
|
|
119819
|
+
return "presentation.pptx";
|
|
119820
|
+
}
|
|
119821
|
+
if (cleaned.length > 200) {
|
|
119822
|
+
const dot = cleaned.lastIndexOf(".");
|
|
119823
|
+
if (dot > 0 && cleaned.length - dot <= 16) {
|
|
119824
|
+
const ext = cleaned.slice(dot);
|
|
119825
|
+
cleaned = cleaned.slice(0, 200 - ext.length) + ext;
|
|
119826
|
+
} else {
|
|
119827
|
+
cleaned = cleaned.slice(0, 200);
|
|
119828
|
+
}
|
|
119829
|
+
}
|
|
119830
|
+
return cleaned;
|
|
119831
|
+
}
|
|
119273
119832
|
function downloadBlob(blob, filename) {
|
|
119833
|
+
const safeName = sanitizeDownloadFilename(filename);
|
|
119274
119834
|
const url = URL.createObjectURL(blob);
|
|
119275
119835
|
const a2 = document.createElement("a");
|
|
119276
119836
|
a2.href = url;
|
|
119277
|
-
a2.download =
|
|
119837
|
+
a2.download = safeName;
|
|
119278
119838
|
document.body.appendChild(a2);
|
|
119279
119839
|
a2.click();
|
|
119280
119840
|
setTimeout(() => {
|
|
@@ -119705,27 +120265,82 @@ function openAutosaveDb2() {
|
|
|
119705
120265
|
req.onerror = () => reject(req.error);
|
|
119706
120266
|
});
|
|
119707
120267
|
}
|
|
119708
|
-
async function
|
|
120268
|
+
async function deleteOldestAutosaveEntry() {
|
|
119709
120269
|
const db = await openAutosaveDb2();
|
|
119710
|
-
return new Promise((resolve2
|
|
119711
|
-
|
|
119712
|
-
|
|
119713
|
-
|
|
119714
|
-
|
|
119715
|
-
|
|
119716
|
-
|
|
119717
|
-
|
|
119718
|
-
|
|
119719
|
-
|
|
119720
|
-
|
|
119721
|
-
|
|
119722
|
-
|
|
119723
|
-
|
|
119724
|
-
|
|
119725
|
-
|
|
119726
|
-
|
|
120270
|
+
return new Promise((resolve2) => {
|
|
120271
|
+
try {
|
|
120272
|
+
const tx = db.transaction(STORE_NAME3, "readwrite");
|
|
120273
|
+
const store = tx.objectStore(STORE_NAME3);
|
|
120274
|
+
let oldestKey = null;
|
|
120275
|
+
let oldestTimestamp = Infinity;
|
|
120276
|
+
const cursorReq = store.openCursor();
|
|
120277
|
+
cursorReq.onsuccess = () => {
|
|
120278
|
+
const cursor = cursorReq.result;
|
|
120279
|
+
if (cursor) {
|
|
120280
|
+
const value = cursor.value;
|
|
120281
|
+
if (typeof value.timestamp === "number" && value.timestamp < oldestTimestamp) {
|
|
120282
|
+
oldestTimestamp = value.timestamp;
|
|
120283
|
+
oldestKey = cursor.primaryKey;
|
|
120284
|
+
}
|
|
120285
|
+
cursor.continue();
|
|
120286
|
+
} else if (oldestKey !== null) {
|
|
120287
|
+
store.delete(oldestKey);
|
|
120288
|
+
}
|
|
120289
|
+
};
|
|
120290
|
+
tx.oncomplete = () => {
|
|
120291
|
+
db.close();
|
|
120292
|
+
resolve2(oldestKey !== null);
|
|
120293
|
+
};
|
|
120294
|
+
tx.onerror = () => {
|
|
120295
|
+
db.close();
|
|
120296
|
+
resolve2(false);
|
|
120297
|
+
};
|
|
120298
|
+
} catch {
|
|
120299
|
+
try {
|
|
120300
|
+
db.close();
|
|
120301
|
+
} catch {
|
|
120302
|
+
}
|
|
120303
|
+
resolve2(false);
|
|
120304
|
+
}
|
|
119727
120305
|
});
|
|
119728
120306
|
}
|
|
120307
|
+
function putAutosaveRecord(filePath, data) {
|
|
120308
|
+
return openAutosaveDb2().then(
|
|
120309
|
+
(db) => new Promise((resolve2, reject) => {
|
|
120310
|
+
const tx = db.transaction(STORE_NAME3, "readwrite");
|
|
120311
|
+
const store = tx.objectStore(STORE_NAME3);
|
|
120312
|
+
store.put({
|
|
120313
|
+
key: filePath,
|
|
120314
|
+
data,
|
|
120315
|
+
timestamp: Date.now(),
|
|
120316
|
+
size: data.byteLength
|
|
120317
|
+
});
|
|
120318
|
+
tx.oncomplete = () => {
|
|
120319
|
+
db.close();
|
|
120320
|
+
resolve2(true);
|
|
120321
|
+
};
|
|
120322
|
+
tx.onerror = () => {
|
|
120323
|
+
db.close();
|
|
120324
|
+
reject(tx.error);
|
|
120325
|
+
};
|
|
120326
|
+
})
|
|
120327
|
+
);
|
|
120328
|
+
}
|
|
120329
|
+
async function saveToIndexedDb(filePath, data) {
|
|
120330
|
+
try {
|
|
120331
|
+
return await putAutosaveRecord(filePath, data);
|
|
120332
|
+
} catch (err) {
|
|
120333
|
+
const errName = err instanceof Error || err instanceof DOMException ? err.name : "";
|
|
120334
|
+
if (errName !== "QuotaExceededError") {
|
|
120335
|
+
throw err;
|
|
120336
|
+
}
|
|
120337
|
+
const deleted = await deleteOldestAutosaveEntry();
|
|
120338
|
+
if (!deleted) {
|
|
120339
|
+
throw err;
|
|
120340
|
+
}
|
|
120341
|
+
return putAutosaveRecord(filePath, data);
|
|
120342
|
+
}
|
|
120343
|
+
}
|
|
119729
120344
|
function useAutosave(input) {
|
|
119730
120345
|
const {
|
|
119731
120346
|
isDirty,
|
|
@@ -119842,6 +120457,25 @@ function collectReferencedFontFamilies(slides) {
|
|
|
119842
120457
|
}
|
|
119843
120458
|
return families;
|
|
119844
120459
|
}
|
|
120460
|
+
var FONT_NAME_UNSAFE_CHARS = /["\\\n\r;}<>]/;
|
|
120461
|
+
var FONT_FORMAT_ALLOWED = /* @__PURE__ */ new Set([
|
|
120462
|
+
"truetype",
|
|
120463
|
+
"opentype",
|
|
120464
|
+
"woff",
|
|
120465
|
+
"woff2",
|
|
120466
|
+
"svg",
|
|
120467
|
+
"embedded-opentype"
|
|
120468
|
+
]);
|
|
120469
|
+
var FONT_DATA_URL_PATTERN = /^data:font\/[a-z0-9+.-]+(?:;charset=[a-z0-9-]+)?;base64,[A-Za-z0-9+/=]+$/i;
|
|
120470
|
+
function isFontDataUrlSafe(url) {
|
|
120471
|
+
if (typeof url !== "string" || url.length === 0) {
|
|
120472
|
+
return false;
|
|
120473
|
+
}
|
|
120474
|
+
if (url.startsWith("blob:")) {
|
|
120475
|
+
return true;
|
|
120476
|
+
}
|
|
120477
|
+
return FONT_DATA_URL_PATTERN.test(url);
|
|
120478
|
+
}
|
|
119845
120479
|
function useFontInjection({ embeddedFonts, slides }) {
|
|
119846
120480
|
useEffect(() => {
|
|
119847
120481
|
if (!embeddedFonts.length) {
|
|
@@ -119849,17 +120483,28 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
119849
120483
|
}
|
|
119850
120484
|
const styleEl = document.createElement("style");
|
|
119851
120485
|
styleEl.id = EMBEDDED_FONTS_STYLE_ID;
|
|
119852
|
-
const cssRules = embeddedFonts.
|
|
120486
|
+
const cssRules = embeddedFonts.flatMap((font) => {
|
|
120487
|
+
if (typeof font.name !== "string" || font.name.length === 0 || FONT_NAME_UNSAFE_CHARS.test(font.name)) {
|
|
120488
|
+
return [];
|
|
120489
|
+
}
|
|
120490
|
+
if (!isFontDataUrlSafe(font.dataUrl)) {
|
|
120491
|
+
return [];
|
|
120492
|
+
}
|
|
120493
|
+
const fontFormat = font.format ?? "truetype";
|
|
120494
|
+
if (!FONT_FORMAT_ALLOWED.has(fontFormat)) {
|
|
120495
|
+
return [];
|
|
120496
|
+
}
|
|
119853
120497
|
const fontWeight = font.bold ? "700" : "400";
|
|
119854
120498
|
const fontStyleCss = font.italic ? "italic" : "normal";
|
|
119855
|
-
|
|
119856
|
-
|
|
120499
|
+
return [
|
|
120500
|
+
`@font-face {
|
|
119857
120501
|
font-family: "${font.name}";
|
|
119858
120502
|
src: url("${font.dataUrl}") format("${fontFormat}");
|
|
119859
120503
|
font-weight: ${fontWeight};
|
|
119860
120504
|
font-style: ${fontStyleCss};
|
|
119861
120505
|
font-display: swap;
|
|
119862
|
-
}
|
|
120506
|
+
}`
|
|
120507
|
+
];
|
|
119863
120508
|
}).join("\n");
|
|
119864
120509
|
styleEl.textContent = cssRules;
|
|
119865
120510
|
document.head.appendChild(styleEl);
|
|
@@ -119888,7 +120533,7 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
119888
120533
|
const linkEl = document.createElement("link");
|
|
119889
120534
|
linkEl.id = GOOGLE_FONTS_LINK_ID;
|
|
119890
120535
|
linkEl.rel = "stylesheet";
|
|
119891
|
-
linkEl.href = `https://fonts.googleapis.com/css2?${googleFamilies.map((f) => `family=${GOOGLE_FONTS_AVAILABLE[f]}`).join("&")}&display=swap`;
|
|
120536
|
+
linkEl.href = `https://fonts.googleapis.com/css2?${googleFamilies.map((f) => `family=${encodeURIComponent(GOOGLE_FONTS_AVAILABLE[f])}`).join("&")}&display=swap`;
|
|
119892
120537
|
document.head.appendChild(linkEl);
|
|
119893
120538
|
return () => {
|
|
119894
120539
|
const existing = document.getElementById(GOOGLE_FONTS_LINK_ID);
|
|
@@ -119904,13 +120549,18 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
119904
120549
|
}
|
|
119905
120550
|
const styleEl = document.createElement("style");
|
|
119906
120551
|
styleEl.id = SYMBOL_FONTS_STYLE_ID;
|
|
119907
|
-
const rules = neededSymbolFonts.
|
|
119908
|
-
(font
|
|
120552
|
+
const rules = neededSymbolFonts.flatMap((font) => {
|
|
120553
|
+
if (typeof font !== "string" || FONT_NAME_UNSAFE_CHARS.test(font)) {
|
|
120554
|
+
return [];
|
|
120555
|
+
}
|
|
120556
|
+
return [
|
|
120557
|
+
`@font-face {
|
|
119909
120558
|
font-family: "${font}";
|
|
119910
120559
|
src: local("${font}"), local("${font} Regular");
|
|
119911
120560
|
font-display: swap;
|
|
119912
120561
|
}`
|
|
119913
|
-
|
|
120562
|
+
];
|
|
120563
|
+
}).join("\n");
|
|
119914
120564
|
styleEl.textContent = rules;
|
|
119915
120565
|
document.head.appendChild(styleEl);
|
|
119916
120566
|
return () => {
|
|
@@ -120053,16 +120703,17 @@ function useLoadContent({
|
|
|
120053
120703
|
`[pptx] Large file detected (${fileSizeMB.toFixed(1)} MB). Loading may use significant memory.`
|
|
120054
120704
|
);
|
|
120055
120705
|
}
|
|
120056
|
-
|
|
120057
|
-
handlerRef.current.dispose();
|
|
120058
|
-
handlerRef.current = null;
|
|
120059
|
-
}
|
|
120706
|
+
const previousHandler = handlerRef.current;
|
|
120060
120707
|
const handler = new PptxHandler();
|
|
120061
120708
|
const parsed = await handler.load(buffer);
|
|
120062
120709
|
if (cancelled || token !== renderTokenRef.current) {
|
|
120063
120710
|
handler.dispose();
|
|
120064
120711
|
return;
|
|
120065
120712
|
}
|
|
120713
|
+
if (previousHandler) {
|
|
120714
|
+
previousHandler.dispose();
|
|
120715
|
+
}
|
|
120716
|
+
handlerRef.current = null;
|
|
120066
120717
|
const mediaElements = [];
|
|
120067
120718
|
for (const slide of parsed.slides) {
|
|
120068
120719
|
collectMediaElements(slide.elements, mediaElements);
|
|
@@ -120107,6 +120758,7 @@ function useLoadContent({
|
|
|
120107
120758
|
})
|
|
120108
120759
|
);
|
|
120109
120760
|
const { paths: imagePaths, refs: imageRefs } = collectImagePaths(parsed.slides);
|
|
120761
|
+
let nextSlides = parsed.slides;
|
|
120110
120762
|
if (imagePaths.size > 0) {
|
|
120111
120763
|
const resolvedMap = /* @__PURE__ */ new Map();
|
|
120112
120764
|
await Promise.all(
|
|
@@ -120120,15 +120772,47 @@ function useLoadContent({
|
|
|
120120
120772
|
}
|
|
120121
120773
|
})
|
|
120122
120774
|
);
|
|
120775
|
+
const elementPatches = /* @__PURE__ */ new Map();
|
|
120123
120776
|
for (const ref of imageRefs) {
|
|
120124
120777
|
const url = resolvedMap.get(ref.path);
|
|
120125
|
-
if (url) {
|
|
120126
|
-
|
|
120778
|
+
if (!url) {
|
|
120779
|
+
continue;
|
|
120127
120780
|
}
|
|
120781
|
+
const id2 = ref.element.id;
|
|
120782
|
+
const existing = elementPatches.get(id2) ?? {};
|
|
120783
|
+
existing[ref.field] = url;
|
|
120784
|
+
elementPatches.set(id2, existing);
|
|
120785
|
+
}
|
|
120786
|
+
if (elementPatches.size > 0) {
|
|
120787
|
+
const patchElements = (elements) => {
|
|
120788
|
+
let mutated = false;
|
|
120789
|
+
const next = elements.map((el) => {
|
|
120790
|
+
let updated = el;
|
|
120791
|
+
const patch = elementPatches.get(el.id);
|
|
120792
|
+
if (patch) {
|
|
120793
|
+
updated = { ...el, ...patch };
|
|
120794
|
+
}
|
|
120795
|
+
if (updated.type === "group" && updated.children?.length) {
|
|
120796
|
+
const newChildren = patchElements(updated.children);
|
|
120797
|
+
if (newChildren !== updated.children) {
|
|
120798
|
+
updated = { ...updated, children: newChildren };
|
|
120799
|
+
}
|
|
120800
|
+
}
|
|
120801
|
+
if (updated !== el) {
|
|
120802
|
+
mutated = true;
|
|
120803
|
+
}
|
|
120804
|
+
return updated;
|
|
120805
|
+
});
|
|
120806
|
+
return mutated ? next : elements;
|
|
120807
|
+
};
|
|
120808
|
+
nextSlides = parsed.slides.map((s) => {
|
|
120809
|
+
const newElements = patchElements(s.elements);
|
|
120810
|
+
return newElements === s.elements ? s : { ...s, elements: newElements };
|
|
120811
|
+
});
|
|
120128
120812
|
}
|
|
120129
120813
|
}
|
|
120130
120814
|
handlerRef.current = handler;
|
|
120131
|
-
setSlides(
|
|
120815
|
+
setSlides(nextSlides);
|
|
120132
120816
|
setTemplateElementsBySlideId({});
|
|
120133
120817
|
setCanvasSize({
|
|
120134
120818
|
width: parsed.width ?? DEFAULT_CANVAS_WIDTH,
|
|
@@ -121302,7 +121986,19 @@ function injectFontFaces(svg, fontFaces) {
|
|
|
121302
121986
|
if (!fontFaces.length) {
|
|
121303
121987
|
return svg;
|
|
121304
121988
|
}
|
|
121305
|
-
const
|
|
121989
|
+
const safeFontFaces = fontFaces.filter((f) => {
|
|
121990
|
+
if (f.css.toLowerCase().includes("</style")) {
|
|
121991
|
+
console.warn(
|
|
121992
|
+
`[export-svg] Dropping @font-face entry for "${f.family}" containing "</style" \u2014 would break out of the <style> block.`
|
|
121993
|
+
);
|
|
121994
|
+
return false;
|
|
121995
|
+
}
|
|
121996
|
+
return true;
|
|
121997
|
+
});
|
|
121998
|
+
if (!safeFontFaces.length) {
|
|
121999
|
+
return svg;
|
|
122000
|
+
}
|
|
122001
|
+
const styleBlock = `<style type="text/css">${safeFontFaces.map((f) => f.css).join("\n")}</style>`;
|
|
121306
122002
|
if (svg.includes("<defs>")) {
|
|
121307
122003
|
return svg.replace("<defs>", `<defs>${styleBlock}`);
|
|
121308
122004
|
}
|
|
@@ -121628,7 +122324,7 @@ function useExportHandlers(input) {
|
|
|
121628
122324
|
activeSlideIndexForGuides,
|
|
121629
122325
|
modalControls
|
|
121630
122326
|
});
|
|
121631
|
-
const handleExportPng = async () => {
|
|
122327
|
+
const handleExportPng = useCallback(async () => {
|
|
121632
122328
|
const stageEl = canvasStageRef.current;
|
|
121633
122329
|
if (!stageEl) {
|
|
121634
122330
|
return;
|
|
@@ -121640,8 +122336,8 @@ function useExportHandlers(input) {
|
|
|
121640
122336
|
} catch (err) {
|
|
121641
122337
|
console.error("[PowerPointViewer] PNG export failed:", err);
|
|
121642
122338
|
}
|
|
121643
|
-
};
|
|
121644
|
-
const handleExportPdf = async () => {
|
|
122339
|
+
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor]);
|
|
122340
|
+
const handleExportPdf = useCallback(async () => {
|
|
121645
122341
|
if (!canvasStageRef.current) {
|
|
121646
122342
|
return;
|
|
121647
122343
|
}
|
|
@@ -121682,8 +122378,8 @@ function useExportHandlers(input) {
|
|
|
121682
122378
|
exportAbortRef.current = null;
|
|
121683
122379
|
setExportModalOpen(false);
|
|
121684
122380
|
}
|
|
121685
|
-
};
|
|
121686
|
-
const handleExportNotesPdf = async () => {
|
|
122381
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
122382
|
+
const handleExportNotesPdf = useCallback(async () => {
|
|
121687
122383
|
if (!canvasStageRef.current) {
|
|
121688
122384
|
return;
|
|
121689
122385
|
}
|
|
@@ -121726,8 +122422,8 @@ function useExportHandlers(input) {
|
|
|
121726
122422
|
exportAbortRef.current = null;
|
|
121727
122423
|
setExportModalOpen(false);
|
|
121728
122424
|
}
|
|
121729
|
-
};
|
|
121730
|
-
const handleCopySlideAsImage = async () => {
|
|
122425
|
+
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex]);
|
|
122426
|
+
const handleCopySlideAsImage = useCallback(async () => {
|
|
121731
122427
|
const stageEl = canvasStageRef.current;
|
|
121732
122428
|
if (!stageEl) {
|
|
121733
122429
|
return;
|
|
@@ -121739,8 +122435,8 @@ function useExportHandlers(input) {
|
|
|
121739
122435
|
} catch (err) {
|
|
121740
122436
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
121741
122437
|
}
|
|
121742
|
-
};
|
|
121743
|
-
const handleExportVideo = async () => {
|
|
122438
|
+
}, [canvasStageRef, activeSlide?.backgroundColor]);
|
|
122439
|
+
const handleExportVideo = useCallback(async () => {
|
|
121744
122440
|
if (!canvasStageRef.current) {
|
|
121745
122441
|
return;
|
|
121746
122442
|
}
|
|
@@ -121782,8 +122478,8 @@ function useExportHandlers(input) {
|
|
|
121782
122478
|
exportAbortRef.current = null;
|
|
121783
122479
|
setExportModalOpen(false);
|
|
121784
122480
|
}
|
|
121785
|
-
};
|
|
121786
|
-
const handleExportGif = async () => {
|
|
122481
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
122482
|
+
const handleExportGif = useCallback(async () => {
|
|
121787
122483
|
if (!canvasStageRef.current) {
|
|
121788
122484
|
return;
|
|
121789
122485
|
}
|
|
@@ -121821,7 +122517,7 @@ function useExportHandlers(input) {
|
|
|
121821
122517
|
exportAbortRef.current = null;
|
|
121822
122518
|
setExportModalOpen(false);
|
|
121823
122519
|
}
|
|
121824
|
-
};
|
|
122520
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
121825
122521
|
const handleCancelExport = useCallback(() => {
|
|
121826
122522
|
exportAbortRef.current?.abort();
|
|
121827
122523
|
exportAbortRef.current = null;
|
|
@@ -121847,6 +122543,15 @@ function useExportHandlers(input) {
|
|
|
121847
122543
|
exportStatusMessage
|
|
121848
122544
|
};
|
|
121849
122545
|
}
|
|
122546
|
+
function escapeHtmlAttr(value) {
|
|
122547
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
122548
|
+
}
|
|
122549
|
+
function safeDataImageSrc(src) {
|
|
122550
|
+
if (typeof src !== "string" || !src.startsWith("data:image/")) {
|
|
122551
|
+
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgAAIAAAUAAen63NgAAAAASUVORK5CYII=";
|
|
122552
|
+
}
|
|
122553
|
+
return escapeHtmlAttr(src);
|
|
122554
|
+
}
|
|
121850
122555
|
function openPrintWindow(title, bodyHtml, orientation, colorFilter, frameSlides) {
|
|
121851
122556
|
const printWindow = window.open("", "_blank", "noopener,noreferrer");
|
|
121852
122557
|
if (!printWindow) {
|
|
@@ -122029,7 +122734,7 @@ function usePrintHandlers(input) {
|
|
|
122029
122734
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
122030
122735
|
if (settings.printWhat === "slides") {
|
|
122031
122736
|
const bodyHtml = slideImages.map(
|
|
122032
|
-
(img, i3) => `<section class="page slide-page"><img class="slide-img" src="${img}" alt="Slide ${slideIndices[i3] + 1}" /></section>`
|
|
122737
|
+
(img, i3) => `<section class="page slide-page"><img class="slide-img" src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3] + 1}" /></section>`
|
|
122033
122738
|
).join("");
|
|
122034
122739
|
openPrintWindow(
|
|
122035
122740
|
"Slides",
|
|
@@ -122045,7 +122750,7 @@ function usePrintHandlers(input) {
|
|
|
122045
122750
|
const idx = slideIndices[i3];
|
|
122046
122751
|
const notes = slides[idx]?.notes?.trim() || "";
|
|
122047
122752
|
return `<section class="page notes-page">
|
|
122048
|
-
<img class="notes-slide" src="${img}" alt="Slide ${idx + 1}" />
|
|
122753
|
+
<img class="notes-slide" src="${safeDataImageSrc(img)}" alt="Slide ${idx + 1}" />
|
|
122049
122754
|
<div class="notes-text">${escapeHtml2(notes)}</div>
|
|
122050
122755
|
</section>`;
|
|
122051
122756
|
}).join("");
|
|
@@ -122077,14 +122782,14 @@ function usePrintHandlers(input) {
|
|
|
122077
122782
|
if (isThreePerPage) {
|
|
122078
122783
|
const rows = Array.from({ length: spp }, (_, cellIndex) => {
|
|
122079
122784
|
const img = pageImgs[cellIndex];
|
|
122080
|
-
const slideCell = img ? `<div class="handout-cell"><img src="${img}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122785
|
+
const slideCell = img ? `<div class="handout-cell"><img src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122081
122786
|
return `<div class="handout-row-3">${slideCell}${buildNoteLines()}</div>`;
|
|
122082
122787
|
}).join("");
|
|
122083
122788
|
pages.push(`<section class="page"><div class="handout-grid-3">${rows}</div></section>`);
|
|
122084
122789
|
} else {
|
|
122085
122790
|
const cells = Array.from({ length: spp }, (_, cellIndex) => {
|
|
122086
122791
|
const img = pageImgs[cellIndex];
|
|
122087
|
-
return img ? `<div class="handout-cell"><img src="${img}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122792
|
+
return img ? `<div class="handout-cell"><img src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122088
122793
|
}).join("");
|
|
122089
122794
|
pages.push(
|
|
122090
122795
|
`<section class="page"><div class="handout-grid" style="grid-template-columns: repeat(${grid.columns}, minmax(0, 1fr)); grid-template-rows: repeat(${grid.rows}, minmax(0, 1fr));">${cells}</div></section>`
|