pptx-angular-viewer 2.6.6 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,8 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [2.6.6](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@2.6.6) - 2026-07-30
8
+
7
9
  ## [2.6.5](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@2.6.5) - 2026-07-30
8
10
 
9
11
  ## [2.6.4](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@2.6.4) - 2026-07-30
@@ -1,4 +1,4 @@
1
- import { t as toChatSummary } from './pptx-angular-viewer-pptx-angular-viewer-DY-f2Dk9.mjs';
1
+ import { t as toChatSummary } from './pptx-angular-viewer-pptx-angular-viewer-CuYqPeQk.mjs';
2
2
 
3
3
  /**
4
4
  * IndexedDB backend for {@link createChatHistoryStore}. Kept in its own module
@@ -103,4 +103,4 @@ function createIdbBackend(db) {
103
103
  }
104
104
 
105
105
  export { CHAT_STORE, createIdbBackend, openChatDb };
106
- //# sourceMappingURL=pptx-angular-viewer-chat-history-idb-RyyNYkYb.mjs.map
106
+ //# sourceMappingURL=pptx-angular-viewer-chat-history-idb-BfgImFmE.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pptx-angular-viewer-chat-history-idb-RyyNYkYb.mjs","sources":["../../src/internal/shared-src/ai/chat-history-idb.ts"],"sourcesContent":["/**\n * IndexedDB backend for {@link createChatHistoryStore}. Kept in its own module\n * so the localStorage fallback and the public factory stay within the per-file\n * size budget. Uses the raw IndexedDB API with tiny promise wrappers so no new\n * runtime dependency is pulled in.\n *\n * Every browser global is touched lazily from inside a function, never at module\n * load, so importing this file in a non-DOM environment (Node, SSR) never throws.\n */\n\nimport type { ChatBackend, PptxAiChatSummary, PptxAiStoredChat } from './chat-history-store';\nimport { toChatSummary } from './chat-history-store';\n\n/** Object store holding one record per chat, keyed by `id`. */\nexport const CHAT_STORE = 'chats';\n/** Index over the optional `deckId` key path, used for per-deck filtering. */\nconst DECK_INDEX = 'deckId';\n\n/** Resolve an `IDBRequest` to a promise. */\nfunction requestToPromise<T>(request: IDBRequest<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\trequest.onsuccess = () => resolve(request.result);\n\t\trequest.onerror = () => reject(request.error ?? new Error('IndexedDB request failed.'));\n\t});\n}\n\n/** Resolve when a transaction commits (or reject on error/abort). */\nfunction transactionDone(tx: IDBTransaction): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\ttx.oncomplete = () => resolve();\n\t\ttx.onerror = () => reject(tx.error ?? new Error('IndexedDB transaction failed.'));\n\t\ttx.onabort = () => reject(tx.error ?? new Error('IndexedDB transaction aborted.'));\n\t});\n}\n\n/**\n * Open (and if needed create/upgrade) the chat database. Throws when there is no\n * `indexedDB` global so the caller can transparently fall back to localStorage.\n */\nexport function openChatDb(dbName: string): Promise<IDBDatabase> {\n\tconst idb = typeof indexedDB !== 'undefined' ? indexedDB : undefined;\n\tif (!idb) {\n\t\tthrow new Error('IndexedDB is not available in this environment.');\n\t}\n\treturn new Promise<IDBDatabase>((resolve, reject) => {\n\t\tconst open = idb.open(dbName, 1);\n\t\topen.onupgradeneeded = () => {\n\t\t\tconst db = open.result;\n\t\t\tif (!db.objectStoreNames.contains(CHAT_STORE)) {\n\t\t\t\tconst store = db.createObjectStore(CHAT_STORE, { keyPath: 'id' });\n\t\t\t\tstore.createIndex(DECK_INDEX, 'deckId', { unique: false });\n\t\t\t}\n\t\t};\n\t\topen.onsuccess = () => resolve(open.result);\n\t\topen.onerror = () => reject(open.error ?? new Error('Failed to open IndexedDB.'));\n\t\topen.onblocked = () => reject(new Error('IndexedDB open blocked by another connection.'));\n\t});\n}\n\n/** Read every stored chat (newest-first ordering is applied by the caller). */\nasync function readAll(db: IDBDatabase, deckId: string | undefined): Promise<PptxAiStoredChat[]> {\n\tconst tx = db.transaction(CHAT_STORE, 'readonly');\n\tconst store = tx.objectStore(CHAT_STORE);\n\tconst source =\n\t\tdeckId === undefined\n\t\t\t? store.getAll()\n\t\t\t: store.index(DECK_INDEX).getAll(IDBKeyRange.only(deckId));\n\tconst rows = await requestToPromise<PptxAiStoredChat[]>(source);\n\tawait transactionDone(tx);\n\treturn rows;\n}\n\n/** Create an IndexedDB-backed {@link ChatBackend}. */\nexport function createIdbBackend(db: IDBDatabase): ChatBackend {\n\treturn {\n\t\tasync list(deckId: string | undefined): Promise<PptxAiChatSummary[]> {\n\t\t\tconst rows = await readAll(db, deckId);\n\t\t\treturn rows.map(toChatSummary).sort((a, b) => b.updatedAt - a.updatedAt);\n\t\t},\n\t\tasync load(id: string): Promise<PptxAiStoredChat | null> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readonly');\n\t\t\tconst row = await requestToPromise<PptxAiStoredChat | undefined>(\n\t\t\t\ttx.objectStore(CHAT_STORE).get(id),\n\t\t\t);\n\t\t\tawait transactionDone(tx);\n\t\t\treturn row ?? null;\n\t\t},\n\t\tasync save(chat: PptxAiStoredChat): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\ttx.objectStore(CHAT_STORE).put(chat);\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t\tasync remove(id: string): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\ttx.objectStore(CHAT_STORE).delete(id);\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t\tasync clear(deckId: string | undefined): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\tconst store = tx.objectStore(CHAT_STORE);\n\t\t\tif (deckId === undefined) {\n\t\t\t\tstore.clear();\n\t\t\t} else {\n\t\t\t\tconst ids = await requestToPromise<IDBValidKey[]>(\n\t\t\t\t\tstore.index(DECK_INDEX).getAllKeys(IDBKeyRange.only(deckId)),\n\t\t\t\t);\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tstore.delete(id);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t};\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pptx-angular-viewer-chat-history-idb-BfgImFmE.mjs","sources":["../../src/internal/shared-src/ai/chat-history-idb.ts"],"sourcesContent":["/**\n * IndexedDB backend for {@link createChatHistoryStore}. Kept in its own module\n * so the localStorage fallback and the public factory stay within the per-file\n * size budget. Uses the raw IndexedDB API with tiny promise wrappers so no new\n * runtime dependency is pulled in.\n *\n * Every browser global is touched lazily from inside a function, never at module\n * load, so importing this file in a non-DOM environment (Node, SSR) never throws.\n */\n\nimport type { ChatBackend, PptxAiChatSummary, PptxAiStoredChat } from './chat-history-store';\nimport { toChatSummary } from './chat-history-store';\n\n/** Object store holding one record per chat, keyed by `id`. */\nexport const CHAT_STORE = 'chats';\n/** Index over the optional `deckId` key path, used for per-deck filtering. */\nconst DECK_INDEX = 'deckId';\n\n/** Resolve an `IDBRequest` to a promise. */\nfunction requestToPromise<T>(request: IDBRequest<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\trequest.onsuccess = () => resolve(request.result);\n\t\trequest.onerror = () => reject(request.error ?? new Error('IndexedDB request failed.'));\n\t});\n}\n\n/** Resolve when a transaction commits (or reject on error/abort). */\nfunction transactionDone(tx: IDBTransaction): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\ttx.oncomplete = () => resolve();\n\t\ttx.onerror = () => reject(tx.error ?? new Error('IndexedDB transaction failed.'));\n\t\ttx.onabort = () => reject(tx.error ?? new Error('IndexedDB transaction aborted.'));\n\t});\n}\n\n/**\n * Open (and if needed create/upgrade) the chat database. Throws when there is no\n * `indexedDB` global so the caller can transparently fall back to localStorage.\n */\nexport function openChatDb(dbName: string): Promise<IDBDatabase> {\n\tconst idb = typeof indexedDB !== 'undefined' ? indexedDB : undefined;\n\tif (!idb) {\n\t\tthrow new Error('IndexedDB is not available in this environment.');\n\t}\n\treturn new Promise<IDBDatabase>((resolve, reject) => {\n\t\tconst open = idb.open(dbName, 1);\n\t\topen.onupgradeneeded = () => {\n\t\t\tconst db = open.result;\n\t\t\tif (!db.objectStoreNames.contains(CHAT_STORE)) {\n\t\t\t\tconst store = db.createObjectStore(CHAT_STORE, { keyPath: 'id' });\n\t\t\t\tstore.createIndex(DECK_INDEX, 'deckId', { unique: false });\n\t\t\t}\n\t\t};\n\t\topen.onsuccess = () => resolve(open.result);\n\t\topen.onerror = () => reject(open.error ?? new Error('Failed to open IndexedDB.'));\n\t\topen.onblocked = () => reject(new Error('IndexedDB open blocked by another connection.'));\n\t});\n}\n\n/** Read every stored chat (newest-first ordering is applied by the caller). */\nasync function readAll(db: IDBDatabase, deckId: string | undefined): Promise<PptxAiStoredChat[]> {\n\tconst tx = db.transaction(CHAT_STORE, 'readonly');\n\tconst store = tx.objectStore(CHAT_STORE);\n\tconst source =\n\t\tdeckId === undefined\n\t\t\t? store.getAll()\n\t\t\t: store.index(DECK_INDEX).getAll(IDBKeyRange.only(deckId));\n\tconst rows = await requestToPromise<PptxAiStoredChat[]>(source);\n\tawait transactionDone(tx);\n\treturn rows;\n}\n\n/** Create an IndexedDB-backed {@link ChatBackend}. */\nexport function createIdbBackend(db: IDBDatabase): ChatBackend {\n\treturn {\n\t\tasync list(deckId: string | undefined): Promise<PptxAiChatSummary[]> {\n\t\t\tconst rows = await readAll(db, deckId);\n\t\t\treturn rows.map(toChatSummary).sort((a, b) => b.updatedAt - a.updatedAt);\n\t\t},\n\t\tasync load(id: string): Promise<PptxAiStoredChat | null> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readonly');\n\t\t\tconst row = await requestToPromise<PptxAiStoredChat | undefined>(\n\t\t\t\ttx.objectStore(CHAT_STORE).get(id),\n\t\t\t);\n\t\t\tawait transactionDone(tx);\n\t\t\treturn row ?? null;\n\t\t},\n\t\tasync save(chat: PptxAiStoredChat): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\ttx.objectStore(CHAT_STORE).put(chat);\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t\tasync remove(id: string): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\ttx.objectStore(CHAT_STORE).delete(id);\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t\tasync clear(deckId: string | undefined): Promise<void> {\n\t\t\tconst tx = db.transaction(CHAT_STORE, 'readwrite');\n\t\t\tconst store = tx.objectStore(CHAT_STORE);\n\t\t\tif (deckId === undefined) {\n\t\t\t\tstore.clear();\n\t\t\t} else {\n\t\t\t\tconst ids = await requestToPromise<IDBValidKey[]>(\n\t\t\t\t\tstore.index(DECK_INDEX).getAllKeys(IDBKeyRange.only(deckId)),\n\t\t\t\t);\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tstore.delete(id);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait transactionDone(tx);\n\t\t},\n\t};\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;AAQG;AAKH;AACO,MAAM,UAAU,GAAG;AAC1B;AACA,MAAM,UAAU,GAAG,QAAQ;AAE3B;AACA,SAAS,gBAAgB,CAAI,OAAsB,EAAA;IAClD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,KAAI;AACzC,QAAA,OAAO,CAAC,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;AACjD,QAAA,OAAO,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AACxF,IAAA,CAAC,CAAC;AACH;AAEA;AACA,SAAS,eAAe,CAAC,EAAkB,EAAA;IAC1C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;QAC5C,EAAE,CAAC,UAAU,GAAG,MAAM,OAAO,EAAE;AAC/B,QAAA,EAAE,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACjF,QAAA,EAAE,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACnF,IAAA,CAAC,CAAC;AACH;AAEA;;;AAGG;AACG,SAAU,UAAU,CAAC,MAAc,EAAA;AACxC,IAAA,MAAM,GAAG,GAAG,OAAO,SAAS,KAAK,WAAW,GAAG,SAAS,GAAG,SAAS;IACpE,IAAI,CAAC,GAAG,EAAE;AACT,QAAA,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC;IACnE;IACA,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,KAAI;QACnD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAChC,QAAA,IAAI,CAAC,eAAe,GAAG,MAAK;AAC3B,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM;YACtB,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;AAC9C,gBAAA,MAAM,KAAK,GAAG,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACjE,gBAAA,KAAK,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3D;AACD,QAAA,CAAC;AACD,QAAA,IAAI,CAAC,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AAC3C,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AACjF,QAAA,IAAI,CAAC,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;AAC1F,IAAA,CAAC,CAAC;AACH;AAEA;AACA,eAAe,OAAO,CAAC,EAAe,EAAE,MAA0B,EAAA;IACjE,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC;IACjD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC;AACxC,IAAA,MAAM,MAAM,GACX,MAAM,KAAK;AACV,UAAE,KAAK,CAAC,MAAM;AACd,UAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5D,IAAA,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAqB,MAAM,CAAC;AAC/D,IAAA,MAAM,eAAe,CAAC,EAAE,CAAC;AACzB,IAAA,OAAO,IAAI;AACZ;AAEA;AACM,SAAU,gBAAgB,CAAC,EAAe,EAAA;IAC/C,OAAO;QACN,MAAM,IAAI,CAAC,MAA0B,EAAA;YACpC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC;YACtC,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;QACzE,CAAC;QACD,MAAM,IAAI,CAAC,EAAU,EAAA;YACpB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC;AACjD,YAAA,MAAM,GAAG,GAAG,MAAM,gBAAgB,CACjC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAClC;AACD,YAAA,MAAM,eAAe,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,IAAI,IAAI;QACnB,CAAC;QACD,MAAM,IAAI,CAAC,IAAsB,EAAA;YAChC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC;YAClD,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACpC,YAAA,MAAM,eAAe,CAAC,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,MAAM,CAAC,EAAU,EAAA;YACtB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC;YAClD,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;AACrC,YAAA,MAAM,eAAe,CAAC,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,KAAK,CAAC,MAA0B,EAAA;YACrC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC;YAClD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC;AACxC,YAAA,IAAI,MAAM,KAAK,SAAS,EAAE;gBACzB,KAAK,CAAC,KAAK,EAAE;YACd;iBAAO;gBACN,MAAM,GAAG,GAAG,MAAM,gBAAgB,CACjC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAC5D;AACD,gBAAA,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE;AACrB,oBAAA,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjB;YACD;AACA,YAAA,MAAM,eAAe,CAAC,EAAE,CAAC;QAC1B,CAAC;KACD;AACF;;;;"}
@@ -26492,6 +26492,101 @@ function generateGeometryMorphAnimation(pair, durationMs, pairIndex, steps = GEO
26492
26492
  };
26493
26493
  }
26494
26494
 
26495
+ /**
26496
+ * Decompose groups that take part in a morph, so a `!!`-named shape can be
26497
+ * matched across a grouping boundary.
26498
+ *
26499
+ * PowerPoint's `!!` naming convention pairs two shapes for Morph by name alone,
26500
+ * wherever they sit in the shape tree: a shape can be top-level on one slide
26501
+ * and nested inside a group on the next, and PowerPoint still carries it
26502
+ * through as one continuing object. Our matcher only ever saw a slide's
26503
+ * TOP-LEVEL elements, so such a pair never matched and both halves faded
26504
+ * instead (issue #131: the wheel deck keeps its centre as a bare shape on the
26505
+ * overview slide and wraps the identical artwork in a `!!Circle` group on every
26506
+ * topic slide).
26507
+ *
26508
+ * A group is decomposed only when it CONTAINS a `!!`-named descendant, which is
26509
+ * the deck author's explicit signal that its contents take part in the morph.
26510
+ * Every other group is left whole, so ordinary grouped artwork keeps animating
26511
+ * as a single unit exactly as before.
26512
+ *
26513
+ * Decomposed children are returned with ABSOLUTE slide coordinates, because
26514
+ * that is the space every downstream geometry calculation (deltas, proximity,
26515
+ * same-box) works in. A binding renders group children as absolutely positioned
26516
+ * boxes inside the group's own box, and the group carries no extra scale, so a
26517
+ * translation delta in slide space is also correct inside the group - which is
26518
+ * what lets the incoming half animate the child's own node in place.
26519
+ *
26520
+ * @module render/morph-flatten
26521
+ */
26522
+ /** Children of `element` when it is a group, else `undefined`. */
26523
+ function groupChildren(element) {
26524
+ if (element.type !== 'group') {
26525
+ return undefined;
26526
+ }
26527
+ const children = element.children;
26528
+ return Array.isArray(children) && children.length > 0 ? children : undefined;
26529
+ }
26530
+ /** Whether `element` or any descendant carries a `!!` morph name. */
26531
+ function containsMorphNamedDescendant(element) {
26532
+ const children = groupChildren(element);
26533
+ if (!children) {
26534
+ return false;
26535
+ }
26536
+ for (const child of children) {
26537
+ if (getElementMorphName(child) !== undefined || containsMorphNamedDescendant(child)) {
26538
+ return true;
26539
+ }
26540
+ }
26541
+ return false;
26542
+ }
26543
+ /**
26544
+ * Re-express a group child in absolute slide coordinates.
26545
+ *
26546
+ * Group children are stored relative to their group's box origin, already in
26547
+ * the group's rendered scale, so an absolute position is the running sum of the
26548
+ * ancestors' origins.
26549
+ */
26550
+ function toAbsolute(child, offsetX, offsetY) {
26551
+ if (offsetX === 0 && offsetY === 0) {
26552
+ return child;
26553
+ }
26554
+ return { ...child, x: child.x + offsetX, y: child.y + offsetY };
26555
+ }
26556
+ /**
26557
+ * The elements of `elements` that a morph should treat as individual units.
26558
+ *
26559
+ * Groups holding a `!!`-named descendant are replaced by their children (in
26560
+ * document order, recursively, in absolute coordinates); everything else is
26561
+ * passed through untouched.
26562
+ */
26563
+ function flattenMorphElements(elements, offsetX = 0, offsetY = 0) {
26564
+ const out = [];
26565
+ for (const element of elements) {
26566
+ const children = groupChildren(element);
26567
+ if (children && containsMorphNamedDescendant(element)) {
26568
+ out.push(...flattenMorphElements(children, offsetX + element.x, offsetY + element.y));
26569
+ continue;
26570
+ }
26571
+ out.push(toAbsolute(element, offsetX, offsetY));
26572
+ }
26573
+ return out;
26574
+ }
26575
+ /**
26576
+ * True when `elements` holds a group that {@link flattenMorphElements} would
26577
+ * decompose. Lets a caller skip the copy entirely for the overwhelmingly common
26578
+ * case of a slide with no `!!`-named group content.
26579
+ */
26580
+ function needsMorphFlattening(elements) {
26581
+ return elements.some((element) => containsMorphNamedDescendant(element));
26582
+ }
26583
+
26584
+ /**
26585
+ * Tolerance (px, slide coordinates) within which two boxes count as identical
26586
+ * for the same-box pass. Sub-pixel only: this pass ignores element type, so it
26587
+ * must never absorb a shape that merely sits close by.
26588
+ */
26589
+ const SAME_BOX_TOLERANCE_PX = 0.5;
26495
26590
  // ---------------------------------------------------------------------------
26496
26591
  // Element name extraction
26497
26592
  // ---------------------------------------------------------------------------
@@ -26604,13 +26699,20 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26604
26699
  const pairs = [];
26605
26700
  const usedFrom = new Set();
26606
26701
  const usedTo = new Set();
26702
+ // A group holding a `!!`-named shape is decomposed into its children (in
26703
+ // absolute coordinates) so that shape can be paired across the grouping
26704
+ // boundary, which is what the `!!` convention is for. Groups without such a
26705
+ // descendant - the overwhelming majority - stay whole and animate as one
26706
+ // unit exactly as before. See `morph-flatten`.
26707
+ const fromElements = flattenMorphElements(fromSlide.elements);
26708
+ const toElements = flattenMorphElements(toSlide.elements);
26607
26709
  // Pass 1: match by !! naming convention
26608
- for (const fromEl of fromSlide.elements) {
26710
+ for (const fromEl of fromElements) {
26609
26711
  const fromName = getElementMorphName(fromEl);
26610
26712
  if (!fromName) {
26611
26713
  continue;
26612
26714
  }
26613
- for (const toEl of toSlide.elements) {
26715
+ for (const toEl of toElements) {
26614
26716
  if (usedTo.has(toEl.id)) {
26615
26717
  continue;
26616
26718
  }
@@ -26634,7 +26736,7 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26634
26736
  }
26635
26737
  return creationIds.get(el.id);
26636
26738
  };
26637
- for (const fromEl of fromSlide.elements) {
26739
+ for (const fromEl of fromElements) {
26638
26740
  if (usedFrom.has(fromEl.id)) {
26639
26741
  continue;
26640
26742
  }
@@ -26642,7 +26744,7 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26642
26744
  if (!fromGuid) {
26643
26745
  continue;
26644
26746
  }
26645
- for (const toEl of toSlide.elements) {
26747
+ for (const toEl of toElements) {
26646
26748
  if (usedTo.has(toEl.id) || fromEl.type !== toEl.type) {
26647
26749
  continue;
26648
26750
  }
@@ -26671,11 +26773,11 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26671
26773
  // and label gliding one sector around the wheel - the reporter's "phantom
26672
26774
  // arrow to another selected item". Such shapes must fall through to the
26673
26775
  // proximity pass (which pairs the same-position counterparts) instead.
26674
- for (const fromEl of fromSlide.elements) {
26776
+ for (const fromEl of fromElements) {
26675
26777
  if (usedFrom.has(fromEl.id) || !fromEl.shapeId) {
26676
26778
  continue;
26677
26779
  }
26678
- for (const toEl of toSlide.elements) {
26780
+ for (const toEl of toElements) {
26679
26781
  if (usedTo.has(toEl.id)) {
26680
26782
  continue;
26681
26783
  }
@@ -26702,13 +26804,13 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26702
26804
  // selection marker mid-glide. Same-shaped counterparts pass at ratio 1;
26703
26805
  // anything more than 2x apart on either axis dissolves in place instead,
26704
26806
  // which is what PowerPoint does with shapes it cannot confidently pair.
26705
- for (const fromEl of fromSlide.elements) {
26807
+ for (const fromEl of fromElements) {
26706
26808
  if (usedFrom.has(fromEl.id)) {
26707
26809
  continue;
26708
26810
  }
26709
26811
  let bestMatch = null;
26710
26812
  let bestDist = Infinity;
26711
- for (const toEl of toSlide.elements) {
26813
+ for (const toEl of toElements) {
26712
26814
  if (usedTo.has(toEl.id)) {
26713
26815
  continue;
26714
26816
  }
@@ -26734,9 +26836,39 @@ function matchMorphElementsFull(fromSlide, toSlide) {
26734
26836
  usedTo.add(bestMatch.id);
26735
26837
  }
26736
26838
  }
26839
+ // Pass 4: pair leftovers that occupy the EXACT same box, even across element
26840
+ // types. A deck often restructures the same visual between slides - the
26841
+ // issue #131 wheel keeps its centre as a bare shape on one slide and wraps
26842
+ // the identical artwork in a group on the others - and PowerPoint carries
26843
+ // that through as one continuing object. Left unmatched, the two halves
26844
+ // fade out and in independently, so the middle of the transition showed the
26845
+ // background straight through a disc that should stay solid.
26846
+ //
26847
+ // The box must agree on all four numbers (within a sub-pixel tolerance),
26848
+ // which is a far stricter test than the proximity pass and cannot pull in a
26849
+ // merely nearby shape.
26850
+ for (const fromEl of fromElements) {
26851
+ if (usedFrom.has(fromEl.id)) {
26852
+ continue;
26853
+ }
26854
+ for (const toEl of toElements) {
26855
+ if (usedTo.has(toEl.id)) {
26856
+ continue;
26857
+ }
26858
+ if (Math.abs(fromEl.x - toEl.x) <= SAME_BOX_TOLERANCE_PX &&
26859
+ Math.abs(fromEl.y - toEl.y) <= SAME_BOX_TOLERANCE_PX &&
26860
+ Math.abs(fromEl.width - toEl.width) <= SAME_BOX_TOLERANCE_PX &&
26861
+ Math.abs(fromEl.height - toEl.height) <= SAME_BOX_TOLERANCE_PX) {
26862
+ pairs.push({ fromElement: fromEl, toElement: toEl });
26863
+ usedFrom.add(fromEl.id);
26864
+ usedTo.add(toEl.id);
26865
+ break;
26866
+ }
26867
+ }
26868
+ }
26737
26869
  // Collect unmatched elements
26738
- const unmatchedFrom = fromSlide.elements.filter((el) => !usedFrom.has(el.id));
26739
- const unmatchedTo = toSlide.elements.filter((el) => !usedTo.has(el.id));
26870
+ const unmatchedFrom = fromElements.filter((el) => !usedFrom.has(el.id));
26871
+ const unmatchedTo = toElements.filter((el) => !usedTo.has(el.id));
26740
26872
  return { pairs, unmatchedFrom, unmatchedTo };
26741
26873
  }
26742
26874
 
@@ -27197,17 +27329,25 @@ function generateMorphAnimations(pairs, durationMs, _mode = 'object') {
27197
27329
  // instead of `rotate(from)->rotate(to)`, sweeping giant arcs across the
27198
27330
  // slide. Flips use the incoming element's, stated after the rotation to
27199
27331
  // match the static order (right-to-left: flip first, then rotate).
27200
- const fromRot = fromElement.rotation ?? 0;
27332
+ // Animate FROM an equivalent start angle that reaches the element's own
27333
+ // authored rotation over the shorter arc; the `to` frame must keep the
27334
+ // authored value so the element lands exactly on its static transform.
27201
27335
  const toRot = toElement.rotation ?? 0;
27336
+ const fromRot = shortestRotationTarget(toRot, fromElement.rotation ?? 0);
27202
27337
  const flips = `${toElement.flipHorizontal ? ' scaleX(-1)' : ''}${toElement.flipVertical ? ' scaleY(-1)' : ''}`;
27203
- // A pair whose appearance changes fades IN over its outgoing ghost (see
27204
- // `generateMorphGhostAnimations`); one that only moves stays fully
27205
- // opaque so the glide reads as a single continuous object.
27206
- const crossfades = morphPairNeedsCrossfade(fromElement, toElement);
27338
+ // A restyled pair dissolves via its outgoing GHOST, which is painted in
27339
+ // the overlay directly above this element and fades 1 -> 0 (see
27340
+ // `generateMorphGhostAnimations`). This half therefore has to stay at its
27341
+ // final opacity for the whole flight: fading it IN as well left both
27342
+ // layers part-transparent in the middle of the transition, so the
27343
+ // background showed straight through what should be a solid object and
27344
+ // both states were legible at once (issue #131: the wheel's centre disc
27345
+ // went see-through mid-morph where PowerPoint keeps it solid and only
27346
+ // dissolves the content on top of it).
27207
27347
  // Build from/to property blocks
27208
27348
  const fromProps = [
27209
27349
  `\t\ttransform: translate(${dx}px, ${dy}px) scale(${sx}, ${sy}) rotate(${fromRot}deg)${flips};`,
27210
- `\t\topacity: ${crossfades ? 0 : fromOpacity};`,
27350
+ `\t\topacity: ${fromOpacity};`,
27211
27351
  ];
27212
27352
  const toProps = [
27213
27353
  `\t\ttransform: translate(0, 0) scale(1, 1) rotate(${toRot}deg)${flips};`,
@@ -27280,8 +27420,10 @@ function generateMorphGhostAnimations(pairs, durationMs, startIndex) {
27280
27420
  const dy = toElement.y + toElement.height / 2 - (fromElement.y + fromElement.height / 2);
27281
27421
  const sx = Math.max(toElement.width, 1) / Math.max(fromElement.width, 1);
27282
27422
  const sy = Math.max(toElement.height, 1) / Math.max(fromElement.height, 1);
27423
+ // The ghost starts on its own authored rotation, so the SHORTEST-arc
27424
+ // adjustment goes on the target angle here (mirror of the incoming half).
27283
27425
  const fromRot = fromElement.rotation ?? 0;
27284
- const toRot = toElement.rotation ?? 0;
27426
+ const toRot = shortestRotationTarget(fromRot, toElement.rotation ?? 0);
27285
27427
  const flips = `${fromElement.flipHorizontal ? ' scaleX(-1)' : ''}${fromElement.flipVertical ? ' scaleY(-1)' : ''}`;
27286
27428
  const keyframes = `
27287
27429
  @keyframes ${safeName} {
@@ -27304,6 +27446,31 @@ function generateMorphGhostAnimations(pairs, durationMs, startIndex) {
27304
27446
  }
27305
27447
  return animations;
27306
27448
  }
27449
+ /**
27450
+ * The target angle to animate TO so the element turns the short way round.
27451
+ *
27452
+ * CSS interpolates `rotate(a)` -> `rotate(b)` numerically, so a pair authored
27453
+ * at 315deg and 0deg spins -315deg (almost a full turn anti-clockwise) when
27454
+ * the shapes are only 45deg apart. PowerPoint always takes the shorter arc.
27455
+ * Returns `fromDeg` plus the delta wrapped into (-180, 180], which is the same
27456
+ * final orientation modulo 360 but the rotation a viewer expects: the issue
27457
+ * #131 deck's wheel points its arrow at the selected wedge by rotating a ring
27458
+ * in 45deg steps, so clicking the neighbouring wedge sent the arrow the long
27459
+ * way around the dial.
27460
+ *
27461
+ * A half turn is ambiguous; +180 (clockwise) is chosen so the direction is at
27462
+ * least deterministic.
27463
+ */
27464
+ function shortestRotationTarget(fromDeg, toDeg) {
27465
+ let delta = (toDeg - fromDeg) % 360;
27466
+ if (delta > 180) {
27467
+ delta -= 360;
27468
+ }
27469
+ else if (delta <= -180) {
27470
+ delta += 360;
27471
+ }
27472
+ return fromDeg + delta;
27473
+ }
27307
27474
  /**
27308
27475
  * Restated static transform suffix (`rotate(N) scaleX(-1) scaleY(-1)`) for an
27309
27476
  * element. Keyframe `transform`s REPLACE the container's static transform, so
@@ -27492,7 +27659,14 @@ function buildMorphTransitionPlan(fromSlide, toSlide, durationMs, mode = 'object
27492
27659
  // Element ids embed their slide path, so the two id spaces do not overlap,
27493
27660
  // but partitioning on this set (rather than on id shape) keeps that an
27494
27661
  // implementation detail of core rather than an assumption here.
27495
- const outgoingElements = [...fromSlide.elements];
27662
+ //
27663
+ // The list is FLATTENED the same way the matcher flattens it (see
27664
+ // `morph-flatten`): a group holding a `!!`-named shape is decomposed into
27665
+ // its children in absolute coordinates, and the animations are keyed by
27666
+ // those children's ids. Painting the undecomposed group here instead would
27667
+ // paint the children twice over - once inside the group, once as their own
27668
+ // ghosts - and leave the group itself without an animation.
27669
+ const outgoingElements = flattenMorphElements(fromSlide.elements);
27496
27670
  const outgoingIds = new Set(outgoingElements.map((element) => element.id));
27497
27671
  const incomingAnimations = new Map();
27498
27672
  const outgoingAnimations = new Map();
@@ -32276,11 +32450,28 @@ const INSTANT = {
32276
32450
  */
32277
32451
  const DEFAULT_TRANSITION_DURATION_MS$1 = 1000;
32278
32452
  /**
32279
- * Default Morph duration (ms). PowerPoint's Morph defaults to 2.00s and does
32280
- * not honour the legacy `spd` speed for it; an authored override arrives as
32281
- * `p14:dur` and lands in `durationMs`, which always wins over this.
32453
+ * Default Morph duration (ms) for a transition that declares NEITHER an
32454
+ * explicit `p14:dur` (which lands in `durationMs` and always wins) NOR a legacy
32455
+ * `spd` speed (see {@link TRANSITION_SPEED_DURATION_MS}). Applying Morph in the
32456
+ * PowerPoint UI writes an explicit duration, so this only covers decks that
32457
+ * declare nothing at all.
32282
32458
  */
32283
32459
  const DEFAULT_MORPH_DURATION_MS = 2000;
32460
+ /**
32461
+ * Duration (ms) for each legacy `p:transition/@spd` speed.
32462
+ *
32463
+ * Measured against PowerPoint itself: the issue #131 deck's morph slides carry
32464
+ * `spd="slow"` and no `p14:dur`, and PowerPoint reports
32465
+ * `SlideShowTransition.Duration = 1.0`. Re-authoring that attribute and
32466
+ * re-reading it through COM gives fast=0.5s, med=0.75s, slow=1.0s - and the
32467
+ * same values for Morph as for every other effect, contradicting the earlier
32468
+ * assumption that Morph ignores `spd`.
32469
+ */
32470
+ const TRANSITION_SPEED_DURATION_MS = {
32471
+ fast: 500,
32472
+ med: 750,
32473
+ slow: 1000,
32474
+ };
32284
32475
  /** Easing applied to every transition animation. */
32285
32476
  const EASE = 'ease-in-out';
32286
32477
 
@@ -33706,10 +33897,15 @@ function resolveTransitionDurationMs(transition) {
33706
33897
  if (typeof transition.durationMs === 'number' && transition.durationMs > 0) {
33707
33898
  return transition.durationMs;
33708
33899
  }
33709
- // PowerPoint's Morph defaults to 2.00s and IGNORES the legacy `spd`
33710
- // attribute for it (the real override lives in `p14:dur`, which core parses
33711
- // into `durationMs` when present). Playing morphs at the generic 1s default
33712
- // made every dissolve feel abrupt next to PowerPoint (issue #131).
33900
+ // The legacy `spd` speed is the next authority, for EVERY effect including
33901
+ // Morph. Verified against PowerPoint via COM (see
33902
+ // `TRANSITION_SPEED_DURATION_MS`): the issue #131 deck's morphs declare
33903
+ // `spd="slow"` and no `p14:dur`, and PowerPoint plays them at 1.0s - we were
33904
+ // playing them at 2.0s, so every transition in that deck ran at half speed.
33905
+ const speedMs = transition.speed ? TRANSITION_SPEED_DURATION_MS[transition.speed] : undefined;
33906
+ if (typeof speedMs === 'number') {
33907
+ return speedMs;
33908
+ }
33713
33909
  if (transition.type === 'morph') {
33714
33910
  return DEFAULT_MORPH_DURATION_MS;
33715
33911
  }
@@ -52853,7 +53049,7 @@ function createLocalStorageBackend(namespace) {
52853
53049
  /** Try IndexedDB first; fall back to localStorage on any failure. */
52854
53050
  async function resolveBackend(dbName, namespace) {
52855
53051
  try {
52856
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-RyyNYkYb.mjs');
53052
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-BfgImFmE.mjs');
52857
53053
  const db = await openChatDb(dbName);
52858
53054
  return createIdbBackend(db);
52859
53055
  }
@@ -85515,7 +85711,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
85515
85711
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
85516
85712
 
85517
85713
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
85518
- const PPTX_ANGULAR_VIEWER_VERSION = "2.6.5";
85714
+ const PPTX_ANGULAR_VIEWER_VERSION = "2.6.6";
85519
85715
 
85520
85716
  /**
85521
85717
  * account-page.component.ts: File > Account content.
@@ -114369,4 +114565,4 @@ function cn(...values) {
114369
114565
  */
114370
114566
 
114371
114567
  export { DATA_TABLE_KEY_W as $, ALIGN_OPTIONS as A, BroadcastDialogComponent as B, CHART_EDITOR_STYLES as C, ChartAxisOptionsComponent as D, ChartAxisStyleOptionsComponent as E, ChartComboTypeOptionsComponent as F, ChartDataEditorComponent as G, ChartDataLabelOptionsComponent as H, ChartDatapointOptionsComponent as I, ChartDisplayOptionsComponent as J, ChartElementViewComponent as K, ChartErrorBarOptionsComponent as L, ChartMarkerOptionsComponent as M, ChartPartSelectionService as N, ChartPrimitivesComponent as O, ChartRendererComponent as P, ChartTrendlineOptionsComponent as Q, CollaborationCursorsComponent as R, CollaborationService as S, ColorChangedImageComponent as T, CommentsPanelComponent as U, CommentsService as V, ComparePanelComponent as W, ConnectorRendererComponent as X, ConnectorTextOverlayComponent as Y, CustomShowsComponent as Z, DATA_TABLE_HEADER_H as _, AUDIENCE_HASH as a, MIN_ZOOM_SCALE as a$, DATA_TABLE_PADDING as a0, DATA_TABLE_ROW_H as a1, DEFAULT_BOUNDS as a2, DEFAULT_BROADCAST_SERVER_URL as a3, DEFAULT_CANVAS_HEIGHT as a4, DEFAULT_CANVAS_WIDTH as a5, DEFAULT_COLOR_SCHEME as a6, DEFAULT_FILL_COLOR as a7, DEFAULT_LAYOUT as a8, DEFAULT_PALETTE$1 as a9, ExportProgressModalComponent as aA, ExportService as aB, FieldContextService as aC, FindBarComponent as aD, FindReplaceBarComponent as aE, FollowModeBarComponent as aF, FontEmbeddingListComponent as aG, FontEmbeddingPanelComponent as aH, GALLERY_THEME_PRESETS as aI, GradientPickerComponent as aJ, HANDOUT_OPTIONS as aK, HeaderFooterDialogComponent as aL, HyperlinkDialogComponent as aM, ImagePropertiesPanelComponent as aN, InkDrawingService as aO, InkRendererComponent as aP, InsertSmartArtDialogComponent as aQ, InspectorPaneHeaderComponent as aR, InspectorPanelComponent as aS, IsMobileService as aT, KeepAnnotationsDialogComponent as aU, LOCALE_CATALOG as aV, LONG_PRESS_DURATION_MS as aW, LONG_PRESS_MOVE_TOLERANCE_PX as aX, LoadContentService as aY, LocalPresencePublisher as aZ, MAX_ZOOM_SCALE as a_, DEFAULT_PRINT_SETTINGS as aa, DEFAULT_SLIDE_BACKGROUND as ab, DEFAULT_STROKE_COLOR as ac, DEFAULT_STYLE as ad, DEFAULT_TABLE_ROW_HEIGHT as ae, DEFAULT_TEXT_COLOR$1 as af, DEFAULT_VIEWER_PROFILE as ag, DIRECTIONAL_PRESETS as ah, DIRECTION_OPTIONS as ai, DocumentPropertiesCardComponent as aj, EMBEDDED_FONTS_STYLE_ID as ak, EMPHASIS_PRESETS as al, ENTRANCE_PRESETS as am, TEMPLATES as an, EXIT_PRESETS as ao, EditorContextMenuComponent as ap, EditorHistory as aq, EditorStateService as ar, EditorToolbarComponent as as, EffectsPanelComponent as at, ElementRendererComponent as au, EmbeddedFontsService as av, EncryptedFileDialogComponent as aw, EquationEditorDialogComponent as ax, EquationRendererComponent as ay, EquationTemplateGalleryComponent as az, AUDIENCE_NONCE_KEY as b, SLIDE_PX_PER_INCH as b$, MediaPreviewComponent as b0, MediaPropertiesPanelComponent as b1, MediaRendererComponent as b2, MediaTrimTimelineComponent as b3, MobileBottomBarComponent as b4, MobileMenuSheetComponent as b5, MobilePresenterViewComponent as b6, MobileSheetComponent as b7, MobileSlidesSheetComponent as b8, MobileToolbarComponent as b9, RESIZE_HANDLES as bA, RULER_THICKNESS as bB, RemoteSelectionOverlayComponent as bC, RibbonAnimationsSectionComponent as bD, RibbonArrangeSectionComponent as bE, RibbonColorPopoverComponent as bF, RibbonComponent as bG, RibbonDesignSectionComponent as bH, RibbonDrawSectionComponent as bI, RibbonDrawingGroupComponent as bJ, RibbonEditingSectionComponent as bK, RibbonFileSectionComponent as bL, RibbonFontControlsComponent as bM, RibbonHomeSectionComponent as bN, RibbonInsertFieldsComponent as bO, RibbonInsertSectionComponent as bP, RibbonParagraphControlsComponent as bQ, RibbonPrimaryRowComponent as bR, RibbonReviewSectionComponent as bS, RibbonSlideshowSectionComponent as bT, RibbonTransitionsSectionComponent as bU, RibbonViewSectionComponent as bV, RulerGuidesService as bW, SEQUENCE_OPTIONS as bX, SEVERITY_GROUPS as bY, SEVERITY_LABELS as bZ, SHORTCUT_REFERENCE_ITEMS as b_, ModalDialogComponent as ba, Model3DRendererComponent as bb, NotesHandoutCardComponent as bc, NotesPanelComponent as bd, NotesToolbarComponent as be, OleRendererComponent as bf, POWER_POINT_VIEWER_PROVIDERS as bg, PRESENTER_CHANNEL_NAME as bh, PRESENTER_MSG_ORIGIN as bi, PasswordProtectionDialogComponent as bj, PasswordStrengthMeterComponent as bk, PowerPointViewerComponent as bl, PresentationAnnotationOverlayComponent as bm, PresentationAnnotationsService as bn, PresentationOverlayComponent as bo, PresentationPropertiesPanelComponent as bp, PresentationSettingsCardComponent as bq, PresentationSubtitleBarComponent as br, PresentationTransitionOverlayComponent as bs, PresenterViewComponent as bt, PresenterWindowService as bu, PrintDialogComponent as bv, PrintService as bw, PrintSettingsPanelComponent as bx, PropertiesDialogComponent as by, REPEAT_MODE_OPTIONS as bz, AVATAR_COLOR_SWATCHES as c, ViewerDocumentPropertiesService as c$, SLIDE_TRANSITION_KEYFRAMES as c0, DEFAULT_PALETTE as c1, PALETTES$1 as c2, SMART_ART_COLOR_SCHEMES as c3, SMART_ART_STYLE_OPTIONS as c4, SUB_ITEM_LABEL as c5, SVG_WARP_PRESETS as c6, SWIPE_MAX_VERTICAL_PX as c7, SWIPE_THRESHOLD_PX as c8, SelectionPaneComponent as c9, TABLE_STRUCTURE_TOGGLES as cA, TEXT_DIRECTION_OPTIONS$1 as cB, THEME_CATALOG as cC, TIMING_CURVE_OPTIONS as cD, TRIGGER_OPTIONS as cE, TYPE_LABELS as cF, TableCellAdvancedFillComponent as cG, TableCellFormattingComponent as cH, TableDataEditorComponent as cI, TablePropertiesComponent as cJ, TableRendererComponent as cK, TableResizeOverlayComponent as cL, TableSelectionService as cM, TextAdvancedPanelComponent as cN, ThemeEditorFieldsComponent as cO, ThemeGalleryComponent as cP, ThemeSelectorCardComponent as cQ, TitleBarComponent as cR, VALIGN_OPTIONS as cS, VIEWER_THEME as cT, VersionHistoryPanelComponent as cU, ViewerCanvasEditingService as cV, ViewerCollabCursorService as cW, ViewerCollaborationSessionService as cX, ViewerCompareService as cY, ViewerCustomShowsService as cZ, ViewerDialogsService as c_, SetUpSlideShowDialogComponent as ca, SettingsAppearanceTabComponent as cb, SettingsDialogComponent as cc, SettingsLanguageTabComponent as cd, ShareDialogComponent as ce, ShortcutPanelComponent as cf, ShowOptionsFieldsetComponent as cg, ShowSlidesFieldsetComponent as ch, SignatureStrippedDialogComponent as ci, SignaturesPanelComponent as cj, SignaturesService as ck, SlideCanvasComponent as cl, SlideDefaultInspectorComponent as cm, SlideDiffChangesComponent as cn, SlideDiffRowComponent as co, SlideDiffThumbnailsComponent as cp, SlideSizeCardComponent as cq, SlideSorterOverlayComponent as cr, SlideThemeOverridePanelComponent as cs, SlidesPanelComponent as ct, SmartArt3DRendererComponent as cu, SmartArt3DService as cv, SmartArtPreviewComponent as cw, SmartArtPropertiesComponent as cx, SmartArtRendererComponent as cy, StatusBarComponent as cz, AccessibilityPanelComponent as d, buildFallbackViewModel as d$, ViewerExportService as d0, ViewerExtraDialogsComponent as d1, ViewerFileIOService as d2, ViewerFindReplaceService as d3, ViewerFormatPainterService as d4, ViewerInspectorPanelService as d5, ViewerKeyboardService as d6, ViewerMobileSheetService as d7, ViewerPresentationModeService as d8, ViewerThemeGalleryService as d9, asMediaElement as dA, assignUserColor as dB, attachTouchGestures as dC, beginNodeEdit as dD, boolFromEvent as dE, bringForward as dF, bringToFront as dG, buildBarActions as dH, buildBroadcastConfig as dI, buildBroadcastViewerUrl as dJ, buildCategoryLabels as dK, buildCellParagraphs as dL, buildChartViewModel as dM, buildChatLogExport as dN, buildChatLogMarkdown as dO, buildChromeStyle as dP, buildClearHyperlinkPatch as dQ, buildClickGroups as dR, buildColStyles as dS, buildCollaborationConfig as dT, buildComboViewModel as dU, buildCssGradientFromShapeStyle as dV, buildDuotoneFilter as dW, buildDuotoneFilterId as dX, buildEmbeddedFontStyles as dY, buildEquationElement as dZ, buildEquationSegment as d_, ViewerTouchGesturesService as da, ViewerZoomService as db, WEBM_MIME_CANDIDATES as dc, WriteBackScheduler as dd, ZoomNavigationService as de, ZoomRendererComponent as df, ZoomTargetService as dg, addCategory as dh, addCommentToList as di, addGradientStopPatch as dj, addItem as dk, addSeries as dl, addSubItem as dm, advanceStep as dn, aiToggleVisible as dp, alignPatch as dq, animationFor as dr, annotationMapToInkInserts as ds, applyAcceptedDiff as dt, applyAnimationPreset as du, applyFindReplacements as dv, applyFormatToElement as dw, applyMove as dx, applyResize as dy, applyTableStylePreset as dz, AccessibilityService as e, computeDataTablePrimitives as e$, buildFontFaceRule as e0, buildGradientFillCss as e1, buildGridlinesAndLabels as e2, buildHyperlinkPatch as e3, buildInkContainerStyle as e4, buildInkStrokes as e5, buildLegend as e6, buildModel3DContainerStyle as e7, buildModel3DViewModel as e8, buildOleActionModel as e9, cellStyleToStyleMap as eA, cellTdStyle as eB, changeCountLabel as eC, changeIcon as eD, characterSpacingPatch as eE, checkFontAvailable as eF, clampCursorPosition as eG, clampGifDimensions as eH, clampIndex as eI, clampNotesFontSize as eJ, clampScale as eK, clampStep as eL, clearAllLocalViewerData as eM, clearAudienceContent as eN, cn as eO, collectAccessibilityIssues as eP, collectElementText as eQ, collectSlideText as eR, collectStoredChats as eS, collectUsedFontFamilies as eT, columnWidthStyle as eU, commitNodeText as eV, computeAlign as eW, computeAxisTitlePrimitives as eX, computeBarRects as eY, computeBubbleRadius as eZ, computeCornerHandle as e_, buildOleInfoRows as ea, buildPatternFillCss as eb, buildPrintHtmlDocument as ec, buildPropertiesPatch as ed, buildRegionMapViewModel as ee, buildSaveSlides as ef, buildShareUrl as eg, buildSmartArtInsertElement as eh, buildSmartArtNodes as ei, buildStockViewModel as ej, buildSurfaceViewModel as ek, buildTableViewModel as el, buildTreemapViewModel as em, buildTrimFragment as en, buildWaterfallViewModel as eo, buildZeroLine as ep, buildZoomContainerStyle as eq, buildZoomViewModel as er, bulletIndentPx as es, canAddTopLevelNode as et, canRemoveTopLevelNode as eu, canStartBroadcast as ev, canStartShare as ew, canUseClipboard as ex, captionDisplayText as ey, cellRunStyle as ez, AccountPageComponent as f, encodeGif as f$, computeDistribute as f0, computeDrawingViewBox as f1, computeErrorBarPrimitives as f2, computeFocusTargets as f3, computeHandleBoxes as f4, computeHandoutLayout as f5, computeIsMobile as f6, computeIsTablet as f7, computeLinePoints as f8, computeLinearRegression as f9, createWebsocketBundle as fA, cssObjectToStyleMap as fB, currentColorScheme as fC, currentLayout as fD, currentStyle as fE, defaultCssVars as fF, defaultRadius as fG, defaultThemeColors as fH, deleteElementsByIds as fI, deleteVersion as fJ, demoteNode as fK, deriveModel3DBlobUrl as fL, derivePresenceList as fM, describeSmartArtBounds as fN, disableGlowPatch as fO, disableInnerShadowPatch as fP, disableOuterShadowPatch as fQ, disableReflectionPatch as fR, disableSoftEdgePatch as fS, duplicateElementById as fT, durationOf as fU, effectsStateOf as fV, enableGlowPatch as fW, enableInnerShadowPatch as fX, enableOuterShadowPatch as fY, enableReflectionPatch as fZ, enableSoftEdgePatch as f_, computePageCount as fa, computePieLayout as fb, computePieSlicePath as fc, computePieSlices as fd, computePlotLayout as fe, computeRSquared as ff, computeRadarPoints as fg, computeScatterDots as fh, computeSelectionBoxes as fi, computeSingleSelected as fj, computeSlideIndices as fk, computeSnap as fl, computeStackedBarRects as fm, computeStackedValueRange as fn, computeTextLines as fo, computeTimerProgress as fp, computeTrendlinePrimitives as fq, computeValueRange as fr, convertOmmlToMathMl as fs, copyFormatFromElement as ft, countAccessibilityIssues as fu, countAnnotationStrokes as fv, createAngularAiBridge as fw, createCustomShow as fx, createSwipeDismissDrag as fy, createWebrtcBundle as fz, ActionSettingsPanelComponent as g, hasAnimation as g$, estimatePageCount as g0, evenColumnWidths as g1, evenRowHeights as g2, exitPresentationFullscreen as g3, exportAiChatLogs as g4, extractPathPoints as g5, eyedropperAvailable as g6, fillColorOf as g7, findInSlides as g8, findOwningSlideIndex as g9, getOleBadgeLabel as gA, getOleDisplayName as gB, getOleDownloadFileName as gC, getOleTypeColor as gD, getOleTypeLabel as gE, getPasswordStrength as gF, getPatternSvg as gG, getPlaceholderStyle as gH, getVersions as gI, getResolvedShapeClipPath as gJ, getResolvedShapeClipPathFor as gK, getShapeFillStrokeStyle as gL, getSlideBackgroundStyle as gM, getSlideTransitionAnimations as gN, getSmartArtNodeBounds as gO, getSpeechRecognitionCtor as gP, getTextBlockStyle as gQ, getTextWarp as gR, getTouchDistance as gS, getWarpCategory as gT, getWarpPath as gU, gradientStateFromStyle as gV, gradientStateOf as gW, gradientStatePatch as gX, gridColumns as gY, groupElements as gZ, groupIssuesBySeverity as g_, findSlideIndexByElementId as ga, fitPolynomial as gb, fitZoom as gc, focusTargetChips as gd, fontMimeForFormat as ge, fontSizeOf as gf, formatAutoNumber as gg, formatAxisValue as gh, formatBytes as gi, formatCursorLabel as gj, formatElapsed as gk, formatFileSize as gl, formatPropertyDate as gm, formatTime as gn, fpsToFrameIntervalMs as go, generateBroadcastRoomId as gp, generateCommentId as gq, generateCustomShowId as gr, generatePressureCircles as gs, generateRulerTicks as gt, getClrChangeParams as gu, getContainerStyle as gv, getDuotoneFilterDef as gw, getImageSrc as gx, getLocalStorageUsageSummary as gy, getOleAriaLabel as gz, AdvancedChartEditorComponent as h, normalizeValue as h$, hasCopyableFormat as h0, hasExistingLink as h1, hasExitedFullscreen as h2, hasGradientFill as h3, hasPressureVariation as h4, hasVisibleSlideAfter as h5, headerLabel as h6, inkViewBox as h7, insertColumn as h8, insertRow as h9, mergeDown as hA, mergeRight as hB, mergeSelection as hC, moveElementBy as hD, moveNodeDown as hE, moveNodeUp as hF, msToFrameDelayCs as hG, narrowToCircle as hH, narrowToPolygon as hI, narrowToRect as hJ, newChartElement as hK, newEquationElement as hL, newPresetShapeElement as hM, newShapeElement as hN, newSmartArtElement as hO, newTableElement as hP, newTextElement as hQ, nextVisibleIndex as hR, nodeBold as hS, nodeEditBox as hT, nodeFillColor as hU, nodeFontColor as hV, nodeIdFromKey as hW, nodeItalic as hX, nodeStyle as hY, normalizeFontFormat as hZ, normalizeSlidesPerPage as h_, interpolateWidth as ha, isAudienceTab as hb, isBold as hc, isBrowserOpenableMime as hd, isChildNode as he, isElementInteractive as hf, isInjectableUrl as hg, isItalic as hh, isPpactionUrl as hi, isPresenterMessage as hj, isSigned as hk, isTextElement as hl, isTwoTableFocus as hm, isUnderline as hn, isUrlSafe as ho, isValidRoomId as hp, isViewportBackgroundPressTarget as hq, isZoomActivationKey as hr, issueTrackKey as hs, issueTypeLabel as ht, keyToLabel as hu, latexToMathml as hv, linePointsToSvgString as hw, lineSpacingPatch as hx, loadAudienceContent as hy, mergeCaptionResults as hz, AiChangeOverlayComponent as i, revealedElementStyles as i$, numFromEvent as i0, ommlToMathml as i1, ooxmlDashToCssBorderStyle as i2, openNativeEyeDropper as i3, overallStatus as i4, paletteColor as i5, parseAudienceNonce as i6, parseNodeTextarea as i7, partitionSlides as i8, patchChartData as i9, removeCommentFromList as iA, removeElementAnimation as iB, removeGradientStopPatch as iC, removeNode as iD, removeRow as iE, removeSeries as iF, renderToCanvas as iG, reorderAnimationDown as iH, reorderAnimationUp as iI, replaceInSlides as iJ, replaceMatch as iK, requestPresentationFullscreen as iL, resizeElement as iM, resolveCaptionTracks as iN, resolveChartKind as iO, resolveFontVariant as iP, resolveHyperlinkHref as iQ, resolveInteractiveElementId as iR, resolveMediaSrc as iS, resolveOleType as iT, resolveParagraphBullet as iU, resolvePresenterNotes as iV, resolveProfileInitial as iW, resolveRegionCode as iX, resolvePalette as iY, resolveThemeCatalogEntry as iZ, resolveTransitionDuration as i_, patchChartStyle as ia, patchTableData as ib, patchTextStyle as ic, pendingElementStyles as id, pickColorByClickFallback as ie, pickSupportedMimeType as ig, planGifFrames as ih, planVideoSegments as ii, pointsToSvgPathD as ij, presenceToCursors as ik, presetByLayout as il, presetsForCategory as im, pressuresToWidths as io, prevVisibleIndex as ip, projectDrawingShapes as iq, promoteNode as ir, provideViewerTheme as is, radarAngle as it, radarRingPoints as iu, recordWebm as iv, redistributeColumnWidth as iw, removeAnimation as ix, removeCategory as iy, removeColumn as iz, AiChatPanelComponent as j, signatureCountLabel as j$, routeOrthogonalConnector as j0, rowStyle as j1, sampleColorFromSlide as j2, sanitizeColor as j3, sanitizeSlideIndex as j4, sanitizeUserName as j5, saveViewerProfile as j6, scanAvailableFonts as j7, searchSlides as j8, seedBroadcastFields as j9, setElementPosition as jA, setGridlineStyle as jB, setLayout as jC, setLegend as jD, setNodeStyle as jE, setNodeText as jF, setRepeatCount as jG, setRepeatMode as jH, setSequence as jI, setSeriesChartType as jJ, setSeriesColor as jK, setSeriesErrorBars as jL, setSeriesMarker as jM, setSeriesName as jN, setSeriesTrendline as jO, setSeriesValue as jP, setStyle as jQ, setTimingCurve as jR, setTitle as jS, setTrigger as jT, setTriggerShapeId as jU, shapeStylePatch as jV, sheetAfterNavigate as jW, shouldBlockClickAdvance as jX, shouldUseSvgWarp as jY, showDirectionPicker as jZ, showsTemplateAffordance as j_, seedHyperlinkDraft as ja, seedPropertiesDraft as jb, seedShareFields as jc, segmentFrameCount as jd, selectValue$2 as je, sendBackward as jf, sendToBack as jg, sequentialColorScale as jh, serializeWriteBack as ji, seriesColor as jj, setAnimationEmphasis as jk, setAnimationEntrance as jl, setAnimationExit as jm, setAxis as jn, setAxisLogScale as jo, setAxisTitleStyle as jp, setCategoryLabel as jq, setCellText as jr, setColorScheme as js, setDataLabels as jt, setDataPointExplosion as ju, setDataPointFill as jv, setDataPointLabel as jw, setDelay as jx, setDirection as jy, setDuration as jz, AiChatService as k, signatureKey as k0, signatureTimestamp as k1, signerName as k2, statusLabel as k3, slideNumberOf as k4, smartArtNodes as k5, paletteColour as k6, snapToGridStep as k7, splitCursorCell as k8, splitMergedCell as k9, updateElementById as kA, updateGlowPatch as kB, updateGradientStopPatch as kC, updateInnerShadowPatch as kD, updateOuterShadowPatch as kE, updateReflectionPatch as kF, vAlignPatch as kG, validatePassword as kH, validatePrintSettings as kI, validateRoomId as kJ, valueToY as kK, vermilionDarkColors as kL, vermilionDarkTheme as kM, vermilionLightColors as kN, vermilionLightTheme as kO, vermilionRadius as kP, waypointsToPathD as kQ, worstStatus as kR, zoomTargetSlideIndex as kS, statusKind as ka, statusLabel$1 as kb, storeAudienceContent as kc, stringFromEvent$5 as kd, strokeColorOf as ke, strokeToInkElement as kf, styleShadowFilter as kg, textAdvancedPatch as kh, textAdvancedStateFromStyle as ki, textAdvancedStateOf as kj, textColorOf as kk, textDirectionPatch as kl, textStyleOf as km, textStylePatch as kn, themeStyle as ko, themeToCssVars as kp, thumbnailHeight as kq, thumbnailZoom as kr, toggleCommentResolvedInList as ks, toggleNodeBold as kt, toggleNodeItalic as ku, toggleSheet as kv, topLevelNodeCount as kw, transformSelectedTextCase as kx, translationsEn as ky, ungroupElements as kz, AiComposerComponent as l, AiFocusBarComponent as m, AiFocusHighlightOverlayComponent as n, AiMessageListComponent as o, AiPanelStore as p, AiProposalCardComponent as q, AiSettingsSectionComponent as r, AiToolCallCardComponent as s, toChatSummary as t, AnimationAuthorPanelComponent as u, AnimationPanelComponent as v, AnimationPlaybackService as w, AutosaveService as x, CURSOR_PALETTE as y, CanvasFitService as z };
114372
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-DY-f2Dk9.mjs.map
114568
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CuYqPeQk.mjs.map