pptx-angular-viewer 1.1.61 → 1.1.62
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.
|
@@ -4946,15 +4946,15 @@ function convertOmmlToLatex(omml) {
|
|
|
4946
4946
|
}
|
|
4947
4947
|
|
|
4948
4948
|
/**
|
|
4949
|
-
* Framework-agnostic chart helpers
|
|
4949
|
+
* Framework-agnostic chart helpers, a focused Vue port of the React package's
|
|
4950
4950
|
* `viewer/utils/chart-helpers.ts`, `chart-layout.ts`, and
|
|
4951
4951
|
* `chart-style-palettes.ts`.
|
|
4952
4952
|
*
|
|
4953
|
-
*
|
|
4954
|
-
* area / pie / doughnut) and the shared chrome
|
|
4955
|
-
* features (log axes, secondary axes, display units,
|
|
4956
|
-
*
|
|
4957
|
-
* `
|
|
4953
|
+
* This module only covers the common-type renderers (bar / column / stacked /
|
|
4954
|
+
* line / area / pie / doughnut) and the shared chrome. Advanced axis/overlay
|
|
4955
|
+
* features (log axes, secondary axes, display units, trendlines, error bars,
|
|
4956
|
+
* data tables) live in `chart-axis.ts` / `chart-axis-render.ts` /
|
|
4957
|
+
* `chart-cartesian.ts` and are consumed via `chart/ChartViewModelSvg.vue`.
|
|
4958
4958
|
*
|
|
4959
4959
|
* These small pure helpers are an extraction candidate: long-term they (and
|
|
4960
4960
|
* their React counterparts) should live in a shared, framework-agnostic
|
|
@@ -22992,6 +22992,164 @@ function observeYDocSlides(ydoc, onChange) {
|
|
|
22992
22992
|
return () => arr.unobserveDeep(onChange);
|
|
22993
22993
|
}
|
|
22994
22994
|
|
|
22995
|
+
/**
|
|
22996
|
+
* collaboration-text-merge.ts: character-level in-place merging of a desired
|
|
22997
|
+
* text state into a live Y.Text.
|
|
22998
|
+
*
|
|
22999
|
+
* `reconcileTextBody` used to replace the whole Y.Text whenever the canonical
|
|
23000
|
+
* decoded form differed, which made concurrent edits to the SAME text element
|
|
23001
|
+
* collide at element granularity (last writer wins). This module instead
|
|
23002
|
+
* applies a minimal edit script to the existing Y.Text:
|
|
23003
|
+
*
|
|
23004
|
+
* - plain-text diff via common prefix/suffix (surrogate-pair safe): one
|
|
23005
|
+
* delete + attributed inserts for the changed middle span
|
|
23006
|
+
* - attribute reconcile: walk the current and desired attribute runs by
|
|
23007
|
+
* position and `format()` only the ranges whose attributes differ
|
|
23008
|
+
*
|
|
23009
|
+
* Because each peer submits a minimal delta, Yjs merges concurrent edits to
|
|
23010
|
+
* the same run at character granularity (e.g. one peer prepends while another
|
|
23011
|
+
* appends, both survive).
|
|
23012
|
+
*/
|
|
23013
|
+
function isYTextEditable(value) {
|
|
23014
|
+
return (isYTextLike(value) &&
|
|
23015
|
+
typeof value.delete === 'function' &&
|
|
23016
|
+
typeof value.format === 'function');
|
|
23017
|
+
}
|
|
23018
|
+
const isHighSurrogate = (code) => code >= 0xd800 && code <= 0xdbff;
|
|
23019
|
+
const isLowSurrogate = (code) => code >= 0xdc00 && code <= 0xdfff;
|
|
23020
|
+
function opsText(ops) {
|
|
23021
|
+
let text = '';
|
|
23022
|
+
for (const op of ops) {
|
|
23023
|
+
if (typeof op.insert === 'string') {
|
|
23024
|
+
text += op.insert;
|
|
23025
|
+
}
|
|
23026
|
+
}
|
|
23027
|
+
return text;
|
|
23028
|
+
}
|
|
23029
|
+
function commonPrefixLength(a, b) {
|
|
23030
|
+
const max = Math.min(a.length, b.length);
|
|
23031
|
+
let i = 0;
|
|
23032
|
+
while (i < max && a.charCodeAt(i) === b.charCodeAt(i)) {
|
|
23033
|
+
i++;
|
|
23034
|
+
}
|
|
23035
|
+
// Never cut between a surrogate pair.
|
|
23036
|
+
if (i > 0 && isHighSurrogate(a.charCodeAt(i - 1))) {
|
|
23037
|
+
i--;
|
|
23038
|
+
}
|
|
23039
|
+
return i;
|
|
23040
|
+
}
|
|
23041
|
+
function commonSuffixLength(a, b, prefix) {
|
|
23042
|
+
const max = Math.min(a.length, b.length) - prefix;
|
|
23043
|
+
let i = 0;
|
|
23044
|
+
while (i < max && a.charCodeAt(a.length - i - 1) === b.charCodeAt(b.length - i - 1)) {
|
|
23045
|
+
i++;
|
|
23046
|
+
}
|
|
23047
|
+
if (i > 0 && isLowSurrogate(a.charCodeAt(a.length - i))) {
|
|
23048
|
+
i--;
|
|
23049
|
+
}
|
|
23050
|
+
return i;
|
|
23051
|
+
}
|
|
23052
|
+
/**
|
|
23053
|
+
* Insert the desired-text span [from, to) into `ytext`, carrying each desired
|
|
23054
|
+
* op's attributes so no character inherits formatting from its neighbour.
|
|
23055
|
+
*/
|
|
23056
|
+
function insertSpanWithAttrs(ytext, desiredOps, from, to) {
|
|
23057
|
+
let opStart = 0;
|
|
23058
|
+
let index = from;
|
|
23059
|
+
for (const op of desiredOps) {
|
|
23060
|
+
if (typeof op.insert !== 'string') {
|
|
23061
|
+
continue;
|
|
23062
|
+
}
|
|
23063
|
+
const opEnd = opStart + op.insert.length;
|
|
23064
|
+
const start = Math.max(opStart, from);
|
|
23065
|
+
const end = Math.min(opEnd, to);
|
|
23066
|
+
if (start < end) {
|
|
23067
|
+
const chunk = op.insert.slice(start - opStart, end - opStart);
|
|
23068
|
+
// Explicit attrs always: attribute-less inserts inherit the previous
|
|
23069
|
+
// character's formatting in Yjs (the style-bleed bug).
|
|
23070
|
+
ytext.insert(index, chunk, (op.attributes ?? {}));
|
|
23071
|
+
index += chunk.length;
|
|
23072
|
+
}
|
|
23073
|
+
opStart = opEnd;
|
|
23074
|
+
}
|
|
23075
|
+
}
|
|
23076
|
+
function attrsEqual(a, b) {
|
|
23077
|
+
const aKeys = Object.keys(a);
|
|
23078
|
+
if (aKeys.length !== Object.keys(b).length) {
|
|
23079
|
+
return false;
|
|
23080
|
+
}
|
|
23081
|
+
return aKeys.every((k) => a[k] === b[k]);
|
|
23082
|
+
}
|
|
23083
|
+
/**
|
|
23084
|
+
* Bring the attribute runs of `ytext` (whose plain text already matches the
|
|
23085
|
+
* desired ops) in line with the desired attributes, formatting only the
|
|
23086
|
+
* ranges that differ.
|
|
23087
|
+
*/
|
|
23088
|
+
function reconcileAttributeRuns(ytext, desiredOps) {
|
|
23089
|
+
const currentOps = ytext.toDelta().filter((op) => typeof op.insert === 'string');
|
|
23090
|
+
let ci = 0;
|
|
23091
|
+
let cOff = 0;
|
|
23092
|
+
let pos = 0;
|
|
23093
|
+
for (const dop of desiredOps) {
|
|
23094
|
+
if (typeof dop.insert !== 'string') {
|
|
23095
|
+
continue;
|
|
23096
|
+
}
|
|
23097
|
+
const dAttrs = (dop.attributes ?? {});
|
|
23098
|
+
let remaining = dop.insert.length;
|
|
23099
|
+
while (remaining > 0 && ci < currentOps.length) {
|
|
23100
|
+
const cText = currentOps[ci].insert;
|
|
23101
|
+
const len = Math.min(cText.length - cOff, remaining);
|
|
23102
|
+
const cAttrs = (currentOps[ci].attributes ?? {});
|
|
23103
|
+
if (!attrsEqual(cAttrs, dAttrs)) {
|
|
23104
|
+
const patch = {};
|
|
23105
|
+
for (const key of Object.keys(dAttrs)) {
|
|
23106
|
+
if (cAttrs[key] !== dAttrs[key]) {
|
|
23107
|
+
patch[key] = dAttrs[key];
|
|
23108
|
+
}
|
|
23109
|
+
}
|
|
23110
|
+
for (const key of Object.keys(cAttrs)) {
|
|
23111
|
+
if (!(key in dAttrs)) {
|
|
23112
|
+
patch[key] = null;
|
|
23113
|
+
}
|
|
23114
|
+
}
|
|
23115
|
+
ytext.format(pos, len, patch);
|
|
23116
|
+
}
|
|
23117
|
+
pos += len;
|
|
23118
|
+
remaining -= len;
|
|
23119
|
+
cOff += len;
|
|
23120
|
+
if (cOff >= cText.length) {
|
|
23121
|
+
ci++;
|
|
23122
|
+
cOff = 0;
|
|
23123
|
+
}
|
|
23124
|
+
}
|
|
23125
|
+
}
|
|
23126
|
+
}
|
|
23127
|
+
/**
|
|
23128
|
+
* Apply the minimal edit script that turns the live `ytext` into the state
|
|
23129
|
+
* described by `desiredOps`. Returns false (leaving the caller to fall back
|
|
23130
|
+
* to wholesale replacement) if the text diff did not converge.
|
|
23131
|
+
*
|
|
23132
|
+
* Must be called inside a Y.Doc transaction when the text is integrated.
|
|
23133
|
+
*/
|
|
23134
|
+
function mergeDeltaIntoYText(ytext, desiredOps) {
|
|
23135
|
+
const currentText = opsText(ytext.toDelta());
|
|
23136
|
+
const desiredText = opsText(desiredOps);
|
|
23137
|
+
if (currentText !== desiredText) {
|
|
23138
|
+
const prefix = commonPrefixLength(currentText, desiredText);
|
|
23139
|
+
const suffix = commonSuffixLength(currentText, desiredText, prefix);
|
|
23140
|
+
const deleteLen = currentText.length - prefix - suffix;
|
|
23141
|
+
if (deleteLen > 0) {
|
|
23142
|
+
ytext.delete(prefix, deleteLen);
|
|
23143
|
+
}
|
|
23144
|
+
insertSpanWithAttrs(ytext, desiredOps, prefix, desiredText.length - suffix);
|
|
23145
|
+
if (opsText(ytext.toDelta()) !== desiredText) {
|
|
23146
|
+
return false;
|
|
23147
|
+
}
|
|
23148
|
+
}
|
|
23149
|
+
reconcileAttributeRuns(ytext, desiredOps);
|
|
23150
|
+
return true;
|
|
23151
|
+
}
|
|
23152
|
+
|
|
22995
23153
|
/**
|
|
22996
23154
|
* collaboration-reconcile.ts: Granular Y.Doc reconciliation for collaborative
|
|
22997
23155
|
* editing.
|
|
@@ -23004,7 +23162,9 @@ function observeYDocSlides(ydoc, onChange) {
|
|
|
23004
23162
|
* - slides and elements are matched by `id`; unchanged ones keep their Y.Map
|
|
23005
23163
|
* instance so concurrent field edits merge via Yjs
|
|
23006
23164
|
* - scalar / complex fields are compared and only set when different
|
|
23007
|
-
* - textBody is
|
|
23165
|
+
* - textBody is edited in place (minimal char-level diff via
|
|
23166
|
+
* collaboration-text-merge.ts) when its canonical decoded form differs;
|
|
23167
|
+
* wholesale replacement is only a fallback
|
|
23008
23168
|
* - removed items are deleted, new ones inserted at their position; moves
|
|
23009
23169
|
* are delete+reinsert (Yjs has no move primitive)
|
|
23010
23170
|
*
|
|
@@ -23053,11 +23213,17 @@ function reconcileTextBody(ymap, rec, factories) {
|
|
|
23053
23213
|
}
|
|
23054
23214
|
return;
|
|
23055
23215
|
}
|
|
23056
|
-
const
|
|
23216
|
+
const desiredDelta = encodeSegmentsToDelta(segments);
|
|
23217
|
+
const desired = decodeDelta(desiredDelta);
|
|
23057
23218
|
const existing = isYTextLike(current) ? decodeDelta(current.toDelta()) : undefined;
|
|
23058
23219
|
if (existing !== undefined && jsonEqual(existing, desired)) {
|
|
23059
23220
|
return;
|
|
23060
23221
|
}
|
|
23222
|
+
// Prefer an in-place minimal edit so concurrent edits to the same text
|
|
23223
|
+
// element merge at character granularity instead of element-level LWW.
|
|
23224
|
+
if (isYTextEditable(current) && mergeDeltaIntoYText(current, desiredDelta)) {
|
|
23225
|
+
return;
|
|
23226
|
+
}
|
|
23061
23227
|
const ytext = factories.createText();
|
|
23062
23228
|
encodeTextBody(segments, ytext);
|
|
23063
23229
|
ymap.set('textBody', ytext);
|
|
@@ -80258,6 +80424,8 @@ const translationsEn = {
|
|
|
80258
80424
|
'pptx.inspector.fill': 'Fill',
|
|
80259
80425
|
'pptx.inspector.line': 'Line',
|
|
80260
80426
|
'pptx.inspector.effects': 'Effects',
|
|
80427
|
+
'pptx.inspector.softEdge': 'Soft Edge',
|
|
80428
|
+
'pptx.inspector.softEdgeRadius': 'Soft Edge Radius',
|
|
80261
80429
|
'pptx.arrange.positionSize': 'Position & Size',
|
|
80262
80430
|
'pptx.arrange.lockElement': 'Lock element',
|
|
80263
80431
|
'pptx.arrange.unlockElement': 'Unlock element',
|
|
@@ -80279,6 +80447,9 @@ const translationsEn = {
|
|
|
80279
80447
|
'pptx.media.trimEndTime': 'End (mm:ss)',
|
|
80280
80448
|
'pptx.media.trimmedDuration': 'Trimmed duration',
|
|
80281
80449
|
'pptx.media.resetTrim': 'Reset trim',
|
|
80450
|
+
'pptx.media.trimErrorNegative': 'Trim times cannot be negative.',
|
|
80451
|
+
'pptx.media.trimErrorStartAfterEnd': 'Trim start must be before trim end.',
|
|
80452
|
+
'pptx.media.trimErrorBeyondDuration': 'Trim times cannot exceed the clip duration.',
|
|
80282
80453
|
'pptx.media.playback': 'Playback',
|
|
80283
80454
|
'pptx.media.volume': 'Volume',
|
|
80284
80455
|
'pptx.media.speed': 'Speed',
|
|
@@ -81513,13 +81684,18 @@ const translationsEn = {
|
|
|
81513
81684
|
'pptx.documentProperties.custom.typeNumber': 'Number',
|
|
81514
81685
|
'pptx.documentProperties.custom.typeText': 'Text',
|
|
81515
81686
|
'pptx.documentProperties.custom.typeYesNo': 'Yes or No',
|
|
81687
|
+
'pptx.documentProperties.statistics.application': 'Application',
|
|
81688
|
+
'pptx.documentProperties.statistics.appVersion': 'Application Version',
|
|
81516
81689
|
'pptx.documentProperties.statistics.elements': 'Elements',
|
|
81517
81690
|
'pptx.documentProperties.statistics.hiddenSlides': 'Hidden Slides',
|
|
81518
81691
|
'pptx.documentProperties.statistics.lastModifiedBy': 'Last Modified By',
|
|
81519
81692
|
'pptx.documentProperties.statistics.notes': 'Notes',
|
|
81520
81693
|
'pptx.documentProperties.statistics.paragraphs': 'Paragraphs',
|
|
81694
|
+
'pptx.documentProperties.statistics.presentationFormat': 'Presentation Format',
|
|
81521
81695
|
'pptx.documentProperties.statistics.revision': 'Revision',
|
|
81522
81696
|
'pptx.documentProperties.statistics.slides': 'Slides',
|
|
81697
|
+
'pptx.documentProperties.statistics.template': 'Template',
|
|
81698
|
+
'pptx.documentProperties.statistics.totalTime': 'Total Editing Time',
|
|
81523
81699
|
'pptx.documentProperties.statistics.words': 'Words',
|
|
81524
81700
|
'pptx.documentProperties.summary.category': 'Category',
|
|
81525
81701
|
'pptx.documentProperties.summary.description': 'Description',
|