pptx-angular-viewer 1.30.0 → 1.31.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.
@@ -19237,6 +19237,17 @@ class EditorHistory {
19237
19237
  constructor(options) {
19238
19238
  this._maxDepth = options?.maxDepth ?? 100;
19239
19239
  }
19240
+ /**
19241
+ * Change the maximum undo depth at runtime (File > Options > Advanced >
19242
+ * "Maximum number of undos"). Trims the past stack immediately if the new
19243
+ * limit is smaller.
19244
+ */
19245
+ setMaxDepth(maxDepth) {
19246
+ this._maxDepth = Math.max(1, Math.floor(maxDepth));
19247
+ while (this._past.length > this._maxDepth) {
19248
+ this._past.shift();
19249
+ }
19250
+ }
19240
19251
  // -- Getters --------------------------------------------------------------
19241
19252
  /** True when at least one undo step is available. */
19242
19253
  get canUndo() {
@@ -25116,7 +25127,12 @@ function decodeDelta(delta) {
25116
25127
  /* skip */
25117
25128
  }
25118
25129
  }
25119
- if (op.insert !== '\n' && op.insert !== '​') {
25130
+ // '\n' is only the synthetic break marker when the op carries a break
25131
+ // attribute; a literal newline TEXT run (no pb/lb) must keep its text or
25132
+ // runs like "Project\nAtlas" collapse to "ProjectAtlas" on decode. The
25133
+ // zero-width space is always the empty-run attribute holder.
25134
+ const isBreakMarker = op.insert === '\n' && (a.pb === '1' || a.lb === '1');
25135
+ if (!isBreakMarker && op.insert !== '​') {
25120
25136
  seg.text = op.insert;
25121
25137
  }
25122
25138
  segments.push(seg);
@@ -37242,6 +37258,1013 @@ function filterVisibleTabs(tabs, hiddenActions) {
37242
37258
  return tabs.filter((tab) => !isActionHidden(tab.id, hiddenActions));
37243
37259
  }
37244
37260
 
37261
+ /**
37262
+ * AutoCorrect-as-you-type engine behind Options > Proofing, mirroring
37263
+ * PowerPoint's replacements: initial-capitals fixes, sentence and day-name
37264
+ * capitalization, smart quotes, double-hyphen to dash, fraction glyphs, and
37265
+ * superscript-style ordinals. Bindings run `applyAutoCorrect` over committed
37266
+ * text (word boundaries, blur, or Enter), never on every keystroke.
37267
+ */
37268
+ const DAY_NAMES = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
37269
+ const FRACTIONS = [
37270
+ ['1/2', '½'],
37271
+ ['1/4', '¼'],
37272
+ ['3/4', '¾'],
37273
+ ];
37274
+ const ORDINAL_SUFFIXES = {
37275
+ st: 'ˢᵗ',
37276
+ nd: 'ⁿᵈ',
37277
+ rd: 'ʳᵈ',
37278
+ th: 'ᵗʰ',
37279
+ };
37280
+ function fixTwoInitialCapitals(word) {
37281
+ if (/^[A-Z]{2}[a-z]/.test(word) && !/^[A-Z]{3,}$/.test(word)) {
37282
+ const second = word.charAt(1).toLowerCase();
37283
+ return `${word.charAt(0)}${second}${word.slice(2)}`;
37284
+ }
37285
+ return word;
37286
+ }
37287
+ function capitalizeDayName(word) {
37288
+ const bare = word.toLowerCase();
37289
+ if (DAY_NAMES.includes(bare) && word === bare) {
37290
+ return `${bare.charAt(0).toUpperCase()}${bare.slice(1)}`;
37291
+ }
37292
+ return word;
37293
+ }
37294
+ function replaceFractions(word) {
37295
+ for (const [plain, glyph] of FRACTIONS) {
37296
+ if (word === plain) {
37297
+ return glyph;
37298
+ }
37299
+ }
37300
+ return word;
37301
+ }
37302
+ function replaceOrdinal(word) {
37303
+ const match = /^(\d+)(st|nd|rd|th)$/i.exec(word);
37304
+ if (!match || match[1] === undefined || match[2] === undefined) {
37305
+ return word;
37306
+ }
37307
+ const superscript = ORDINAL_SUFFIXES[match[2].toLowerCase()];
37308
+ return superscript ? `${match[1]}${superscript}` : word;
37309
+ }
37310
+ function transformWord(word, proofing) {
37311
+ let result = word;
37312
+ if (proofing.autoCorrectTwoInitialCapitals) {
37313
+ result = fixTwoInitialCapitals(result);
37314
+ }
37315
+ if (proofing.autoCorrectCapitalizeDayNames) {
37316
+ result = capitalizeDayName(result);
37317
+ }
37318
+ if (proofing.autoCorrectFractions) {
37319
+ result = replaceFractions(result);
37320
+ }
37321
+ if (proofing.autoCorrectOrdinals) {
37322
+ result = replaceOrdinal(result);
37323
+ }
37324
+ return result;
37325
+ }
37326
+ function applySmartQuotes(text) {
37327
+ let result = '';
37328
+ for (let i = 0; i < text.length; i += 1) {
37329
+ const char = text.charAt(i);
37330
+ if (char !== '"' && char !== "'") {
37331
+ result += char;
37332
+ continue;
37333
+ }
37334
+ const previous = i === 0 ? '' : text.charAt(i - 1);
37335
+ const opening = previous === '' || /[\s([{‘“-]/.test(previous);
37336
+ if (char === '"') {
37337
+ result += opening ? '“' : '”';
37338
+ }
37339
+ else {
37340
+ result += opening ? '‘' : '’';
37341
+ }
37342
+ }
37343
+ return result;
37344
+ }
37345
+ function applyHyphensToDash(text) {
37346
+ return text.replace(/(\S)--(?=\S)/g, '$1—').replace(/ -- /g, ' – ');
37347
+ }
37348
+ function capitalizeSentences(text) {
37349
+ return text.replace(/(^|[.!?]\s+)([a-z])/g, (_match, lead, letter) => `${lead}${letter.toUpperCase()}`);
37350
+ }
37351
+ /** Apply every enabled AutoCorrect rule to a committed run of text. */
37352
+ function applyAutoCorrect(text, proofing) {
37353
+ if (text.length === 0) {
37354
+ return text;
37355
+ }
37356
+ let result = text;
37357
+ if (proofing.autoCorrectSmartQuotes) {
37358
+ result = applySmartQuotes(result);
37359
+ }
37360
+ if (proofing.autoCorrectHyphensToDash) {
37361
+ result = applyHyphensToDash(result);
37362
+ }
37363
+ const needsWordPass = proofing.autoCorrectTwoInitialCapitals ||
37364
+ proofing.autoCorrectCapitalizeDayNames ||
37365
+ proofing.autoCorrectFractions ||
37366
+ proofing.autoCorrectOrdinals;
37367
+ if (needsWordPass) {
37368
+ result = result
37369
+ .split(/(\s+)/)
37370
+ .map((part) => (/^\s+$/.test(part) ? part : transformWord(part, proofing)))
37371
+ .join('');
37372
+ }
37373
+ if (proofing.autoCorrectCapitalizeFirstLetter) {
37374
+ result = capitalizeSentences(result);
37375
+ }
37376
+ return result;
37377
+ }
37378
+
37379
+ /**
37380
+ * Quick Access Toolbar command catalog and list-editing helpers, backing the
37381
+ * Options > Quick Access Toolbar pane and the title-bar QAT strip.
37382
+ *
37383
+ * Ids map onto actions every binding already exposes; each binding resolves
37384
+ * an id to its own icon + handler when rendering the strip.
37385
+ */
37386
+ const QUICK_ACCESS_COMMAND_CATALOG = [
37387
+ { id: 'save', labelKey: 'pptx.toolbar.save', icon: 'save' },
37388
+ { id: 'undo', labelKey: 'pptx.toolbar.undo', icon: 'undo' },
37389
+ { id: 'redo', labelKey: 'pptx.toolbar.redo', icon: 'redo' },
37390
+ {
37391
+ id: 'presentFromStart',
37392
+ labelKey: 'pptx.options.quickAccess.command.presentFromStart',
37393
+ icon: 'play',
37394
+ },
37395
+ { id: 'print', labelKey: 'pptx.options.quickAccess.command.print', icon: 'printer' },
37396
+ { id: 'exportPdf', labelKey: 'pptx.options.quickAccess.command.exportPdf', icon: 'fileDown' },
37397
+ { id: 'newSlide', labelKey: 'pptx.options.quickAccess.command.newSlide', icon: 'plus' },
37398
+ { id: 'spellCheck', labelKey: 'pptx.settings.spellCheck', icon: 'spellCheck' },
37399
+ { id: 'zoomIn', labelKey: 'pptx.options.quickAccess.command.zoomIn', icon: 'zoomIn' },
37400
+ { id: 'zoomOut', labelKey: 'pptx.options.quickAccess.command.zoomOut', icon: 'zoomOut' },
37401
+ ];
37402
+ const DEFAULT_QUICK_ACCESS_COMMAND_IDS = [
37403
+ 'save',
37404
+ 'undo',
37405
+ 'redo',
37406
+ 'presentFromStart',
37407
+ ];
37408
+ function getQuickAccessCommand(id) {
37409
+ return QUICK_ACCESS_COMMAND_CATALOG.find((entry) => entry.id === id);
37410
+ }
37411
+ /** Commands not yet on the toolbar, in catalog order. */
37412
+ function availableQuickAccessCommands(commandIds) {
37413
+ return QUICK_ACCESS_COMMAND_CATALOG.filter((entry) => !commandIds.includes(entry.id));
37414
+ }
37415
+ function addQuickAccessCommand(commandIds, id) {
37416
+ if (commandIds.includes(id) || !getQuickAccessCommand(id)) {
37417
+ return [...commandIds];
37418
+ }
37419
+ return [...commandIds, id];
37420
+ }
37421
+ function removeQuickAccessCommand(commandIds, id) {
37422
+ return commandIds.filter((entry) => entry !== id);
37423
+ }
37424
+ function moveQuickAccessCommand(commandIds, id, direction) {
37425
+ const index = commandIds.indexOf(id);
37426
+ const target = direction === 'up' ? index - 1 : index + 1;
37427
+ if (index < 0 || target < 0 || target >= commandIds.length) {
37428
+ return [...commandIds];
37429
+ }
37430
+ const next = [...commandIds];
37431
+ const swapped = next[target];
37432
+ if (swapped === undefined) {
37433
+ return next;
37434
+ }
37435
+ next[target] = id;
37436
+ next[index] = swapped;
37437
+ return next;
37438
+ }
37439
+
37440
+ /**
37441
+ * Options > Add-ins pane model: the viewer's optional capability modules,
37442
+ * presented the way PowerPoint lists COM add-ins (name / location / type,
37443
+ * grouped by active state). Bindings supply the runtime availability flags.
37444
+ */
37445
+ const VIEWER_ADDIN_CATALOG = [
37446
+ {
37447
+ id: 'smartArt3d',
37448
+ nameKey: 'pptx.options.addIns.smartArt3d',
37449
+ descriptionKey: 'pptx.options.addIns.smartArt3dDescription',
37450
+ type: 'renderer',
37451
+ location: 'pptx-viewer-shared/smartart-3d',
37452
+ },
37453
+ {
37454
+ id: 'model3d',
37455
+ nameKey: 'pptx.options.addIns.model3d',
37456
+ descriptionKey: 'pptx.options.addIns.model3dDescription',
37457
+ type: 'renderer',
37458
+ location: 'pptx-viewer-shared (three)',
37459
+ },
37460
+ {
37461
+ id: 'emfConverter',
37462
+ nameKey: 'pptx.options.addIns.emfConverter',
37463
+ descriptionKey: 'pptx.options.addIns.emfConverterDescription',
37464
+ type: 'converter',
37465
+ location: 'emf-converter',
37466
+ },
37467
+ {
37468
+ id: 'mtxDecompressor',
37469
+ nameKey: 'pptx.options.addIns.mtxDecompressor',
37470
+ descriptionKey: 'pptx.options.addIns.mtxDecompressorDescription',
37471
+ type: 'converter',
37472
+ location: 'mtx-decompressor',
37473
+ },
37474
+ {
37475
+ id: 'collaboration',
37476
+ nameKey: 'pptx.options.addIns.collaboration',
37477
+ descriptionKey: 'pptx.options.addIns.collaborationDescription',
37478
+ type: 'collaboration',
37479
+ location: 'pptx-viewer-shared (collaboration)',
37480
+ },
37481
+ {
37482
+ id: 'locales',
37483
+ nameKey: 'pptx.options.addIns.locales',
37484
+ descriptionKey: 'pptx.options.addIns.localesDescription',
37485
+ type: 'localization',
37486
+ location: 'pptx-viewer-locales',
37487
+ },
37488
+ ];
37489
+ /** Rows for the Add-ins table, split into active/inactive by the host's status flags. */
37490
+ function resolveViewerAddinRows(status) {
37491
+ return VIEWER_ADDIN_CATALOG.map((definition) => ({
37492
+ ...definition,
37493
+ active: status?.[definition.id] ?? true,
37494
+ }));
37495
+ }
37496
+
37497
+ const DEFAULT_VIEWER_OPTIONS = {
37498
+ general: {
37499
+ displayOptimization: 'appearance',
37500
+ showMiniToolbar: true,
37501
+ enableLivePreview: true,
37502
+ collapseRibbonAutomatically: false,
37503
+ collapseSearchByDefault: false,
37504
+ screenTipStyle: 'descriptions',
37505
+ userName: '',
37506
+ userInitials: '',
37507
+ showStartScreen: true,
37508
+ },
37509
+ proofing: {
37510
+ autoCorrectTwoInitialCapitals: true,
37511
+ autoCorrectCapitalizeFirstLetter: true,
37512
+ autoCorrectCapitalizeDayNames: true,
37513
+ autoCorrectSmartQuotes: true,
37514
+ autoCorrectHyphensToDash: true,
37515
+ autoCorrectFractions: true,
37516
+ autoCorrectOrdinals: true,
37517
+ ignoreUppercase: true,
37518
+ ignoreWordsWithNumbers: true,
37519
+ ignoreInternetAddresses: true,
37520
+ flagRepeatedWords: true,
37521
+ checkSpellingAsYouType: false,
37522
+ hideSpellingErrors: false,
37523
+ },
37524
+ save: {
37525
+ autoSave: true,
37526
+ autoRecoverIntervalMinutes: 2,
37527
+ keepLastAutoRecoveredVersion: true,
37528
+ defaultExportFormat: 'pptx',
37529
+ embedFonts: false,
37530
+ embedAllFontCharacters: false,
37531
+ cacheRetentionDays: 14,
37532
+ clearCacheOnClose: false,
37533
+ },
37534
+ accessibility: {
37535
+ showAccessibilityStatus: true,
37536
+ feedbackWithSound: false,
37537
+ soundScheme: 'modern',
37538
+ showShortcutKeysInScreenTips: true,
37539
+ reducedMotion: false,
37540
+ },
37541
+ advanced: {
37542
+ autoSelectEntireWord: true,
37543
+ allowTextDragAndDrop: true,
37544
+ maximumUndoSteps: 100,
37545
+ useSmartCutAndPaste: true,
37546
+ showPasteOptionsButton: true,
37547
+ imageDefaultResolution: 'highFidelity',
37548
+ doNotCompressImages: false,
37549
+ chartPropertiesFollowDataPoint: true,
37550
+ recentPresentationsCount: 50,
37551
+ showVerticalRuler: false,
37552
+ showGrid: false,
37553
+ snapToGrid: false,
37554
+ disableHardwareAcceleration: false,
37555
+ openDocumentsView: 'savedView',
37556
+ slideShowShowMenuOnRightClick: true,
37557
+ slideShowShowPopupToolbar: true,
37558
+ slideShowPromptKeepInkAnnotations: true,
37559
+ slideShowEndWithBlackSlide: true,
37560
+ printInBackground: true,
37561
+ printHighQuality: false,
37562
+ printUseMostRecentSettings: true,
37563
+ printWhat: 'slides',
37564
+ printColorMode: 'color',
37565
+ printHiddenSlides: false,
37566
+ printScaleToFit: false,
37567
+ printFrameSlides: false,
37568
+ },
37569
+ ribbon: { hiddenTabIds: [] },
37570
+ quickAccess: {
37571
+ visible: true,
37572
+ position: 'above',
37573
+ showCommandLabels: false,
37574
+ commandIds: ['save', 'undo', 'redo', 'presentFromStart'],
37575
+ },
37576
+ trust: {
37577
+ openInProtectedView: false,
37578
+ allowExternalContent: true,
37579
+ confirmExternalHyperlinks: true,
37580
+ },
37581
+ };
37582
+ function cloneOptions(options) {
37583
+ return {
37584
+ general: { ...options.general },
37585
+ proofing: { ...options.proofing },
37586
+ save: { ...options.save },
37587
+ accessibility: { ...options.accessibility },
37588
+ advanced: { ...options.advanced },
37589
+ ribbon: { hiddenTabIds: [...options.ribbon.hiddenTabIds] },
37590
+ quickAccess: { ...options.quickAccess, commandIds: [...options.quickAccess.commandIds] },
37591
+ trust: { ...options.trust },
37592
+ };
37593
+ }
37594
+ /** Merge a persisted partial over the defaults, dropping unknown keys. */
37595
+ function mergeViewerOptions(stored) {
37596
+ const merged = cloneOptions(DEFAULT_VIEWER_OPTIONS);
37597
+ if (!stored || typeof stored !== 'object') {
37598
+ return merged;
37599
+ }
37600
+ for (const groupId of Object.keys(merged)) {
37601
+ const patch = stored[groupId];
37602
+ if (!patch || typeof patch !== 'object') {
37603
+ continue;
37604
+ }
37605
+ const target = merged[groupId];
37606
+ const defaults = DEFAULT_VIEWER_OPTIONS[groupId];
37607
+ for (const [key, value] of Object.entries(patch)) {
37608
+ if (!(key in defaults) || value === undefined) {
37609
+ continue;
37610
+ }
37611
+ const defaultValue = defaults[key];
37612
+ if (Array.isArray(defaultValue)) {
37613
+ if (Array.isArray(value)) {
37614
+ target[key] = value.filter((entry) => typeof entry === 'string');
37615
+ }
37616
+ }
37617
+ else if (typeof value === typeof defaultValue) {
37618
+ target[key] = value;
37619
+ }
37620
+ }
37621
+ }
37622
+ return merged;
37623
+ }
37624
+ /** Sparse diff of `options` against the defaults, for lean persistence. */
37625
+ function diffViewerOptions(options) {
37626
+ const diff = {};
37627
+ for (const groupId of Object.keys(DEFAULT_VIEWER_OPTIONS)) {
37628
+ const defaults = DEFAULT_VIEWER_OPTIONS[groupId];
37629
+ const current = options[groupId];
37630
+ let groupDiff;
37631
+ for (const key of Object.keys(defaults)) {
37632
+ const defaultValue = defaults[key];
37633
+ const value = current[key];
37634
+ const changed = Array.isArray(defaultValue)
37635
+ ? JSON.stringify(defaultValue) !== JSON.stringify(value)
37636
+ : defaultValue !== value;
37637
+ if (changed) {
37638
+ groupDiff ??= {};
37639
+ groupDiff[key] = value;
37640
+ }
37641
+ }
37642
+ if (groupDiff) {
37643
+ diff[groupId] = groupDiff;
37644
+ }
37645
+ }
37646
+ return diff;
37647
+ }
37648
+ /** Project the full options model onto the legacy six-toggle preferences surface. */
37649
+ function viewerOptionsToPreferences(options) {
37650
+ return {
37651
+ autoSave: options.save.autoSave,
37652
+ spellCheck: options.proofing.checkSpellingAsYouType,
37653
+ showGrid: options.advanced.showGrid,
37654
+ showRulers: options.advanced.showVerticalRuler,
37655
+ snapToGrid: options.advanced.snapToGrid,
37656
+ reducedMotion: options.accessibility.reducedMotion,
37657
+ };
37658
+ }
37659
+ /** Apply a legacy preference toggle back onto the options model. */
37660
+ function applyPreferenceToOptions(options, key, value) {
37661
+ const next = cloneOptions(options);
37662
+ switch (key) {
37663
+ case 'autoSave':
37664
+ next.save.autoSave = value;
37665
+ break;
37666
+ case 'spellCheck':
37667
+ next.proofing.checkSpellingAsYouType = value;
37668
+ break;
37669
+ case 'showGrid':
37670
+ next.advanced.showGrid = value;
37671
+ break;
37672
+ case 'showRulers':
37673
+ next.advanced.showVerticalRuler = value;
37674
+ break;
37675
+ case 'snapToGrid':
37676
+ next.advanced.snapToGrid = value;
37677
+ break;
37678
+ case 'reducedMotion':
37679
+ next.accessibility.reducedMotion = value;
37680
+ break;
37681
+ }
37682
+ return next;
37683
+ }
37684
+
37685
+ /**
37686
+ * Pure helpers that translate File > Options values into the behaviors the
37687
+ * bindings actually wire: history depth, autosave cadence, tooltips, ribbon
37688
+ * visibility, print defaults, image export quality, and protected view.
37689
+ */
37690
+ /** Maximum undo steps for `EditorHistory({ maxDepth })`. */
37691
+ function resolveHistoryDepth(options) {
37692
+ const steps = Math.round(options.advanced.maximumUndoSteps);
37693
+ return Math.min(150, Math.max(3, Number.isFinite(steps) ? steps : 100));
37694
+ }
37695
+ /** AutoRecover cadence in seconds, honoring the shared minimum. */
37696
+ function resolveAutosaveIntervalSeconds(options) {
37697
+ const seconds = Math.round(options.save.autoRecoverIntervalMinutes * 60);
37698
+ return Math.max(AUTOSAVE_MIN_INTERVAL_SECONDS, Number.isFinite(seconds) ? seconds : 120);
37699
+ }
37700
+ /**
37701
+ * Tooltip text for a chrome control under the current ScreenTip style:
37702
+ * `off` suppresses tooltips entirely, `plain` drops the description, and
37703
+ * shortcut hints append only while Accessibility > shortcut keys is on.
37704
+ */
37705
+ function resolveScreenTip(options, label, description, shortcut) {
37706
+ const style = options.general.screenTipStyle;
37707
+ if (style === 'off') {
37708
+ return undefined;
37709
+ }
37710
+ let tip = label;
37711
+ if (style === 'descriptions' && description) {
37712
+ tip = `${tip}: ${description}`;
37713
+ }
37714
+ if (shortcut && options.accessibility.showShortcutKeysInScreenTips) {
37715
+ tip = `${tip} (${shortcut})`;
37716
+ }
37717
+ return tip;
37718
+ }
37719
+ /** Ribbon tabs after Customize Ribbon hiding; the File tab always survives. */
37720
+ function resolveVisibleRibbonTabs(options, tabs = TOOLBAR_TABS) {
37721
+ const hidden = new Set(options.ribbon.hiddenTabIds);
37722
+ hidden.delete('file');
37723
+ return tabs.filter((tab) => !hidden.has(tab.id));
37724
+ }
37725
+ /**
37726
+ * Seed for print dialogs when "use the following print settings" is chosen;
37727
+ * `undefined` keeps each dialog's own most-recent settings (PowerPoint's
37728
+ * "Use the most recently used print settings").
37729
+ */
37730
+ function resolveDefaultPrintSettings(options) {
37731
+ if (options.advanced.printUseMostRecentSettings) {
37732
+ return undefined;
37733
+ }
37734
+ return {
37735
+ printWhat: options.advanced.printWhat,
37736
+ colorMode: options.advanced.printColorMode,
37737
+ frameSlides: options.advanced.printFrameSlides,
37738
+ };
37739
+ }
37740
+ /** Target raster density in ppi for image export; `undefined` = lossless/high fidelity. */
37741
+ function resolveImageResolutionPpi(preset) {
37742
+ switch (preset) {
37743
+ case 'ppi330':
37744
+ return 330;
37745
+ case 'ppi220':
37746
+ return 220;
37747
+ case 'ppi150':
37748
+ return 150;
37749
+ case 'ppi96':
37750
+ return 96;
37751
+ default:
37752
+ return undefined;
37753
+ }
37754
+ }
37755
+ /** Raster scale multiplier relative to the standard 96 ppi CSS pixel grid. */
37756
+ function resolveImageResolutionScale(options) {
37757
+ if (options.advanced.doNotCompressImages) {
37758
+ return 1;
37759
+ }
37760
+ const ppi = resolveImageResolutionPpi(options.advanced.imageDefaultResolution);
37761
+ return ppi === undefined ? 1 : Math.max(0.25, Math.min(4, ppi / 96));
37762
+ }
37763
+ /** Whether the viewer should open documents read-only until editing is enabled. */
37764
+ function shouldOpenInProtectedView(options) {
37765
+ return options.trust.openInProtectedView;
37766
+ }
37767
+ /** Whether following an external hyperlink should ask for confirmation first. */
37768
+ function shouldConfirmExternalHyperlink(options, href) {
37769
+ if (!options.trust.confirmExternalHyperlinks) {
37770
+ return false;
37771
+ }
37772
+ return /^https?:/i.test(href);
37773
+ }
37774
+ /** CSS class list for the viewer root reflecting display-affecting options. */
37775
+ function resolveOptionRootClasses(options, prefix) {
37776
+ const classes = [];
37777
+ if (options.accessibility.reducedMotion) {
37778
+ classes.push(`${prefix}-reduced-motion`);
37779
+ }
37780
+ if (options.advanced.disableHardwareAcceleration) {
37781
+ classes.push(`${prefix}-no-hw-accel`);
37782
+ }
37783
+ if (options.general.displayOptimization === 'compatibility') {
37784
+ classes.push(`${prefix}-compat-display`);
37785
+ }
37786
+ return classes;
37787
+ }
37788
+ /** Play the Accessibility > "feedback with sound" cue for a completed action. */
37789
+ function playFeedbackSound(options) {
37790
+ if (!options.accessibility.feedbackWithSound || typeof window === 'undefined') {
37791
+ return;
37792
+ }
37793
+ const AudioContextCtor = window.AudioContext;
37794
+ if (!AudioContextCtor) {
37795
+ return;
37796
+ }
37797
+ try {
37798
+ const context = new AudioContextCtor();
37799
+ const oscillator = context.createOscillator();
37800
+ const gain = context.createGain();
37801
+ const modern = options.accessibility.soundScheme === 'modern';
37802
+ oscillator.frequency.value = modern ? 880 : 660;
37803
+ oscillator.type = modern ? 'sine' : 'square';
37804
+ gain.gain.setValueAtTime(0.04, context.currentTime);
37805
+ gain.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 0.15);
37806
+ oscillator.connect(gain).connect(context.destination);
37807
+ oscillator.start();
37808
+ oscillator.stop(context.currentTime + 0.16);
37809
+ oscillator.onended = () => {
37810
+ void context.close();
37811
+ };
37812
+ }
37813
+ catch {
37814
+ // Audio unavailable (autoplay policy, headless env): stay silent.
37815
+ }
37816
+ }
37817
+
37818
+ function toggle(group, key, labelKey, extra) {
37819
+ return { kind: 'toggle', group, key, labelKey, ...extra };
37820
+ }
37821
+ function select(group, key, labelKey, choiceList) {
37822
+ return { kind: 'select', group, key, labelKey, choices: choiceList };
37823
+ }
37824
+ function numberControl(group, key, labelKey, min, max, unitKey) {
37825
+ return { kind: 'number', group, key, labelKey, min, max, unitKey };
37826
+ }
37827
+ function textControl(group, key, labelKey) {
37828
+ return { kind: 'text', group, key, labelKey, maxLength: 64 };
37829
+ }
37830
+ function choices(prefix, values) {
37831
+ return values.map((value) => ({ value, labelKey: `${prefix}.${value}` }));
37832
+ }
37833
+ const SCREEN_TIP_CHOICES = choices('pptx.options.screenTipStyle', [
37834
+ 'descriptions',
37835
+ 'plain',
37836
+ 'off',
37837
+ ]);
37838
+
37839
+ /** Advanced, Customize Ribbon, Quick Access, Add-ins, and Trust Center tabs. */
37840
+ const ADVANCED_TAB = {
37841
+ id: 'advanced',
37842
+ labelKey: 'pptx.options.advanced.label',
37843
+ descriptionKey: 'pptx.options.advanced.description',
37844
+ sections: [
37845
+ {
37846
+ id: 'editing',
37847
+ titleKey: 'pptx.options.advanced.editing',
37848
+ controls: [
37849
+ toggle('advanced', 'autoSelectEntireWord', 'pptx.options.advanced.autoSelectWord'),
37850
+ toggle('advanced', 'allowTextDragAndDrop', 'pptx.options.advanced.textDragAndDrop'),
37851
+ numberControl('advanced', 'maximumUndoSteps', 'pptx.options.advanced.maximumUndoSteps', 3, 150),
37852
+ ],
37853
+ },
37854
+ {
37855
+ id: 'cutCopyPaste',
37856
+ titleKey: 'pptx.options.advanced.cutCopyPaste',
37857
+ controls: [
37858
+ toggle('advanced', 'useSmartCutAndPaste', 'pptx.options.advanced.smartCutAndPaste'),
37859
+ toggle('advanced', 'showPasteOptionsButton', 'pptx.options.advanced.showPasteOptions'),
37860
+ ],
37861
+ },
37862
+ {
37863
+ id: 'imageQuality',
37864
+ titleKey: 'pptx.options.advanced.imageQuality',
37865
+ controls: [
37866
+ toggle('advanced', 'doNotCompressImages', 'pptx.options.advanced.doNotCompressImages'),
37867
+ select('advanced', 'imageDefaultResolution', 'pptx.options.advanced.defaultResolution', choices('pptx.options.resolution', [
37868
+ 'highFidelity',
37869
+ 'ppi330',
37870
+ 'ppi220',
37871
+ 'ppi150',
37872
+ 'ppi96',
37873
+ ])),
37874
+ ],
37875
+ },
37876
+ {
37877
+ id: 'chart',
37878
+ titleKey: 'pptx.options.advanced.chart',
37879
+ controls: [
37880
+ toggle('advanced', 'chartPropertiesFollowDataPoint', 'pptx.options.advanced.chartFollowDataPoint'),
37881
+ ],
37882
+ },
37883
+ {
37884
+ id: 'display',
37885
+ titleKey: 'pptx.options.advanced.display',
37886
+ controls: [
37887
+ numberControl('advanced', 'recentPresentationsCount', 'pptx.options.advanced.recentCount', 0, 50),
37888
+ toggle('advanced', 'showVerticalRuler', 'pptx.settings.showRulers'),
37889
+ toggle('advanced', 'showGrid', 'pptx.settings.showGrid'),
37890
+ toggle('advanced', 'snapToGrid', 'pptx.settings.snapToGrid'),
37891
+ toggle('advanced', 'disableHardwareAcceleration', 'pptx.options.advanced.disableHardwareAcceleration'),
37892
+ select('advanced', 'openDocumentsView', 'pptx.options.advanced.openDocumentsView', choices('pptx.options.openView', [
37893
+ 'savedView',
37894
+ 'normal',
37895
+ 'outline',
37896
+ 'slideSorter',
37897
+ 'notes',
37898
+ ])),
37899
+ ],
37900
+ },
37901
+ {
37902
+ id: 'slideShow',
37903
+ titleKey: 'pptx.options.advanced.slideShow',
37904
+ controls: [
37905
+ toggle('advanced', 'slideShowShowMenuOnRightClick', 'pptx.options.advanced.showMenuOnRightClick'),
37906
+ toggle('advanced', 'slideShowShowPopupToolbar', 'pptx.options.advanced.showPopupToolbar'),
37907
+ toggle('advanced', 'slideShowPromptKeepInkAnnotations', 'pptx.options.advanced.promptKeepInk'),
37908
+ toggle('advanced', 'slideShowEndWithBlackSlide', 'pptx.options.advanced.endWithBlackSlide'),
37909
+ ],
37910
+ },
37911
+ {
37912
+ id: 'print',
37913
+ titleKey: 'pptx.options.advanced.print',
37914
+ controls: [
37915
+ toggle('advanced', 'printInBackground', 'pptx.options.advanced.printInBackground'),
37916
+ toggle('advanced', 'printHighQuality', 'pptx.options.advanced.printHighQuality'),
37917
+ toggle('advanced', 'printUseMostRecentSettings', 'pptx.options.advanced.printUseMostRecent'),
37918
+ select('advanced', 'printWhat', 'pptx.options.advanced.printWhat', choices('pptx.options.printWhat', ['slides', 'handouts', 'notes', 'outline'])),
37919
+ select('advanced', 'printColorMode', 'pptx.options.advanced.printColorMode', choices('pptx.options.printColorMode', ['color', 'grayscale', 'blackAndWhite'])),
37920
+ toggle('advanced', 'printHiddenSlides', 'pptx.options.advanced.printHiddenSlides', {
37921
+ indent: true,
37922
+ }),
37923
+ toggle('advanced', 'printScaleToFit', 'pptx.options.advanced.printScaleToFit', {
37924
+ indent: true,
37925
+ }),
37926
+ toggle('advanced', 'printFrameSlides', 'pptx.options.advanced.printFrameSlides', {
37927
+ indent: true,
37928
+ }),
37929
+ ],
37930
+ },
37931
+ ],
37932
+ };
37933
+ const RIBBON_TAB = {
37934
+ id: 'ribbon',
37935
+ labelKey: 'pptx.options.ribbon.label',
37936
+ descriptionKey: 'pptx.options.ribbon.description',
37937
+ custom: 'ribbon',
37938
+ sections: [
37939
+ {
37940
+ id: 'shortcutReference',
37941
+ titleKey: 'pptx.settings.keyboardShortcuts',
37942
+ special: 'shortcutReference',
37943
+ controls: [],
37944
+ },
37945
+ ],
37946
+ };
37947
+ const QUICK_ACCESS_TAB = {
37948
+ id: 'quickAccess',
37949
+ labelKey: 'pptx.options.quickAccess.label',
37950
+ descriptionKey: 'pptx.options.quickAccess.description',
37951
+ custom: 'quickAccess',
37952
+ sections: [
37953
+ {
37954
+ id: 'quickAccessOptions',
37955
+ titleKey: 'pptx.options.quickAccess.optionsTitle',
37956
+ controls: [
37957
+ toggle('quickAccess', 'visible', 'pptx.options.quickAccess.show'),
37958
+ select('quickAccess', 'position', 'pptx.options.quickAccess.position', choices('pptx.options.quickAccessPosition', ['above', 'below'])),
37959
+ toggle('quickAccess', 'showCommandLabels', 'pptx.options.quickAccess.showLabels'),
37960
+ ],
37961
+ },
37962
+ ],
37963
+ };
37964
+ const ADD_INS_TAB = {
37965
+ id: 'addIns',
37966
+ labelKey: 'pptx.options.addIns.label',
37967
+ descriptionKey: 'pptx.options.addIns.description',
37968
+ custom: 'addIns',
37969
+ sections: [],
37970
+ };
37971
+ const TRUST_TAB = {
37972
+ id: 'trust',
37973
+ labelKey: 'pptx.options.trust.label',
37974
+ descriptionKey: 'pptx.options.trust.description',
37975
+ sections: [
37976
+ {
37977
+ id: 'trustSettings',
37978
+ titleKey: 'pptx.options.trust.settingsTitle',
37979
+ descriptionKey: 'pptx.options.trust.settingsDescription',
37980
+ controls: [
37981
+ toggle('trust', 'openInProtectedView', 'pptx.options.trust.protectedView', {
37982
+ infoKey: 'pptx.options.trust.protectedViewInfo',
37983
+ }),
37984
+ toggle('trust', 'allowExternalContent', 'pptx.options.trust.allowExternalContent', {
37985
+ infoKey: 'pptx.options.trust.allowExternalContentInfo',
37986
+ }),
37987
+ toggle('trust', 'confirmExternalHyperlinks', 'pptx.options.trust.confirmHyperlinks'),
37988
+ ],
37989
+ },
37990
+ ],
37991
+ };
37992
+
37993
+ /** General, Proofing, Save, Language, and Accessibility tab definitions. */
37994
+ const GENERAL_TAB = {
37995
+ id: 'general',
37996
+ labelKey: 'pptx.settings.general',
37997
+ descriptionKey: 'pptx.options.general.description',
37998
+ sections: [
37999
+ {
38000
+ id: 'userInterface',
38001
+ titleKey: 'pptx.options.general.userInterface',
38002
+ controls: [
38003
+ select('general', 'displayOptimization', 'pptx.options.general.displayOptimization', choices('pptx.options.displayOptimization', ['appearance', 'compatibility'])),
38004
+ toggle('general', 'showMiniToolbar', 'pptx.options.general.showMiniToolbar', {
38005
+ infoKey: 'pptx.options.general.showMiniToolbarInfo',
38006
+ }),
38007
+ toggle('general', 'enableLivePreview', 'pptx.options.general.enableLivePreview', {
38008
+ infoKey: 'pptx.options.general.enableLivePreviewInfo',
38009
+ }),
38010
+ toggle('general', 'collapseRibbonAutomatically', 'pptx.options.general.collapseRibbon'),
38011
+ toggle('general', 'collapseSearchByDefault', 'pptx.options.general.collapseSearch'),
38012
+ select('general', 'screenTipStyle', 'pptx.options.general.screenTipStyle', SCREEN_TIP_CHOICES),
38013
+ ],
38014
+ },
38015
+ {
38016
+ id: 'personalize',
38017
+ titleKey: 'pptx.options.general.personalize',
38018
+ controls: [
38019
+ textControl('general', 'userName', 'pptx.options.general.userName'),
38020
+ textControl('general', 'userInitials', 'pptx.options.general.userInitials'),
38021
+ ],
38022
+ },
38023
+ {
38024
+ id: 'appearance',
38025
+ titleKey: 'pptx.options.general.appearance',
38026
+ special: 'themePicker',
38027
+ controls: [],
38028
+ },
38029
+ {
38030
+ id: 'startup',
38031
+ titleKey: 'pptx.options.general.startup',
38032
+ controls: [toggle('general', 'showStartScreen', 'pptx.options.general.showStartScreen')],
38033
+ },
38034
+ ],
38035
+ };
38036
+ const PROOFING_TAB = {
38037
+ id: 'proofing',
38038
+ labelKey: 'pptx.options.proofing.label',
38039
+ descriptionKey: 'pptx.options.proofing.description',
38040
+ sections: [
38041
+ {
38042
+ id: 'autoCorrect',
38043
+ titleKey: 'pptx.options.proofing.autoCorrect',
38044
+ descriptionKey: 'pptx.options.proofing.autoCorrectDescription',
38045
+ controls: [
38046
+ toggle('proofing', 'autoCorrectTwoInitialCapitals', 'pptx.options.proofing.twoInitialCapitals'),
38047
+ toggle('proofing', 'autoCorrectCapitalizeFirstLetter', 'pptx.options.proofing.capitalizeFirstLetter'),
38048
+ toggle('proofing', 'autoCorrectCapitalizeDayNames', 'pptx.options.proofing.capitalizeDayNames'),
38049
+ toggle('proofing', 'autoCorrectSmartQuotes', 'pptx.options.proofing.smartQuotes'),
38050
+ toggle('proofing', 'autoCorrectHyphensToDash', 'pptx.options.proofing.hyphensToDash'),
38051
+ toggle('proofing', 'autoCorrectFractions', 'pptx.options.proofing.fractions'),
38052
+ toggle('proofing', 'autoCorrectOrdinals', 'pptx.options.proofing.ordinals'),
38053
+ ],
38054
+ },
38055
+ {
38056
+ id: 'spellingOffice',
38057
+ titleKey: 'pptx.options.proofing.spellingOffice',
38058
+ controls: [
38059
+ toggle('proofing', 'ignoreUppercase', 'pptx.options.proofing.ignoreUppercase'),
38060
+ toggle('proofing', 'ignoreWordsWithNumbers', 'pptx.options.proofing.ignoreWordsWithNumbers'),
38061
+ toggle('proofing', 'ignoreInternetAddresses', 'pptx.options.proofing.ignoreInternetAddresses'),
38062
+ toggle('proofing', 'flagRepeatedWords', 'pptx.options.proofing.flagRepeatedWords'),
38063
+ ],
38064
+ },
38065
+ {
38066
+ id: 'spellingViewer',
38067
+ titleKey: 'pptx.options.proofing.spellingViewer',
38068
+ controls: [
38069
+ toggle('proofing', 'checkSpellingAsYouType', 'pptx.options.proofing.checkSpellingAsYouType'),
38070
+ toggle('proofing', 'hideSpellingErrors', 'pptx.options.proofing.hideSpellingErrors', {
38071
+ indent: true,
38072
+ }),
38073
+ ],
38074
+ },
38075
+ ],
38076
+ };
38077
+ const SAVE_TAB = {
38078
+ id: 'save',
38079
+ labelKey: 'pptx.options.save.label',
38080
+ descriptionKey: 'pptx.options.save.description',
38081
+ sections: [
38082
+ {
38083
+ id: 'savePresentations',
38084
+ titleKey: 'pptx.options.save.savePresentations',
38085
+ controls: [
38086
+ toggle('save', 'autoSave', 'pptx.options.save.autoSave', {
38087
+ infoKey: 'pptx.options.save.autoSaveInfo',
38088
+ }),
38089
+ select('save', 'defaultExportFormat', 'pptx.options.save.defaultFormat', choices('pptx.options.saveFormat', ['pptx', 'pdf', 'png'])),
38090
+ numberControl('save', 'autoRecoverIntervalMinutes', 'pptx.options.save.autoRecoverInterval', 1, 120, 'pptx.options.save.minutes'),
38091
+ toggle('save', 'keepLastAutoRecoveredVersion', 'pptx.options.save.keepLastAutoRecovered', {
38092
+ indent: true,
38093
+ }),
38094
+ ],
38095
+ },
38096
+ {
38097
+ id: 'fidelity',
38098
+ titleKey: 'pptx.options.save.fidelity',
38099
+ controls: [
38100
+ toggle('save', 'embedFonts', 'pptx.options.save.embedFonts', {
38101
+ infoKey: 'pptx.options.save.embedFontsInfo',
38102
+ }),
38103
+ toggle('save', 'embedAllFontCharacters', 'pptx.options.save.embedAllCharacters', {
38104
+ indent: true,
38105
+ }),
38106
+ ],
38107
+ },
38108
+ {
38109
+ id: 'cache',
38110
+ titleKey: 'pptx.options.save.cache',
38111
+ special: 'clearCache',
38112
+ controls: [
38113
+ numberControl('save', 'cacheRetentionDays', 'pptx.options.save.cacheRetentionDays', 1, 90, 'pptx.options.save.days'),
38114
+ toggle('save', 'clearCacheOnClose', 'pptx.options.save.clearCacheOnClose'),
38115
+ ],
38116
+ },
38117
+ ],
38118
+ };
38119
+ const LANGUAGE_TAB = {
38120
+ id: 'language',
38121
+ labelKey: 'pptx.settings.language',
38122
+ descriptionKey: 'pptx.options.language.description',
38123
+ custom: 'language',
38124
+ sections: [],
38125
+ };
38126
+ const ACCESSIBILITY_TAB = {
38127
+ id: 'accessibility',
38128
+ labelKey: 'pptx.options.accessibility.label',
38129
+ descriptionKey: 'pptx.options.accessibility.description',
38130
+ sections: [
38131
+ {
38132
+ id: 'assistant',
38133
+ titleKey: 'pptx.options.accessibility.assistant',
38134
+ controls: [
38135
+ toggle('accessibility', 'showAccessibilityStatus', 'pptx.options.accessibility.showStatus'),
38136
+ ],
38137
+ },
38138
+ {
38139
+ id: 'feedback',
38140
+ titleKey: 'pptx.options.accessibility.feedback',
38141
+ controls: [
38142
+ toggle('accessibility', 'feedbackWithSound', 'pptx.options.accessibility.feedbackWithSound'),
38143
+ select('accessibility', 'soundScheme', 'pptx.options.accessibility.soundScheme', choices('pptx.options.soundScheme', ['modern', 'classic'])),
38144
+ ],
38145
+ },
38146
+ {
38147
+ id: 'display',
38148
+ titleKey: 'pptx.options.accessibility.display',
38149
+ controls: [
38150
+ select('general', 'screenTipStyle', 'pptx.options.general.screenTipStyle', SCREEN_TIP_CHOICES),
38151
+ toggle('accessibility', 'showShortcutKeysInScreenTips', 'pptx.options.accessibility.showShortcutKeys'),
38152
+ toggle('accessibility', 'reducedMotion', 'pptx.settings.reducedMotion'),
38153
+ ],
38154
+ },
38155
+ ],
38156
+ };
38157
+
38158
+ /**
38159
+ * The ten File > Options categories, in PowerPoint's order. Bindings render
38160
+ * the dialog's category list and panes from this array.
38161
+ */
38162
+ const VIEWER_OPTIONS_TABS = [
38163
+ GENERAL_TAB,
38164
+ PROOFING_TAB,
38165
+ SAVE_TAB,
38166
+ LANGUAGE_TAB,
38167
+ ACCESSIBILITY_TAB,
38168
+ ADVANCED_TAB,
38169
+ RIBBON_TAB,
38170
+ QUICK_ACCESS_TAB,
38171
+ ADD_INS_TAB,
38172
+ TRUST_TAB,
38173
+ ];
38174
+ function getViewerOptionsTab(id) {
38175
+ const tab = VIEWER_OPTIONS_TABS.find((entry) => entry.id === id);
38176
+ if (!tab) {
38177
+ throw new Error(`Unknown viewer options tab: ${id}`);
38178
+ }
38179
+ return tab;
38180
+ }
38181
+
38182
+ function createViewerOptionsStore(init) {
38183
+ const persist = init?.persist !== false;
38184
+ const seeded = mergeViewerOptions(init?.initial);
38185
+ let options = persist ? overlayStored(seeded, readStoredViewerPrefs().options) : seeded;
38186
+ const listeners = new Set();
38187
+ function commit(next) {
38188
+ options = next;
38189
+ if (persist) {
38190
+ writeStoredViewerPrefs({ options: diffViewerOptions(next) });
38191
+ }
38192
+ for (const listener of listeners) {
38193
+ listener(options);
38194
+ }
38195
+ }
38196
+ return {
38197
+ getOptions: () => options,
38198
+ setOptions: (next) => commit(cloneOptions(next)),
38199
+ setValue: (group, key, value) => {
38200
+ const defaults = DEFAULT_VIEWER_OPTIONS[group];
38201
+ if (!(key in defaults) || typeof defaults[key] !== typeof value) {
38202
+ return;
38203
+ }
38204
+ const next = cloneOptions(options);
38205
+ next[group][key] = value;
38206
+ commit(next);
38207
+ },
38208
+ getValue: (group, key) => {
38209
+ const record = options[group];
38210
+ const value = record[key];
38211
+ return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'
38212
+ ? value
38213
+ : undefined;
38214
+ },
38215
+ setRibbonTabHidden: (tabId, hidden) => {
38216
+ if (tabId === 'file') {
38217
+ return;
38218
+ }
38219
+ const current = options.ribbon.hiddenTabIds;
38220
+ const has = current.includes(tabId);
38221
+ if (hidden === has) {
38222
+ return;
38223
+ }
38224
+ const next = cloneOptions(options);
38225
+ next.ribbon.hiddenTabIds = hidden
38226
+ ? [...current, tabId]
38227
+ : current.filter((id) => id !== tabId);
38228
+ commit(next);
38229
+ },
38230
+ setQuickAccessCommands: (commandIds) => {
38231
+ const next = cloneOptions(options);
38232
+ next.quickAccess.commandIds = [...commandIds];
38233
+ commit(next);
38234
+ },
38235
+ reset: (group) => {
38236
+ if (!group) {
38237
+ commit(cloneOptions(DEFAULT_VIEWER_OPTIONS));
38238
+ return;
38239
+ }
38240
+ const next = cloneOptions(options);
38241
+ const defaults = cloneOptions(DEFAULT_VIEWER_OPTIONS);
38242
+ next[group] = defaults[group];
38243
+ commit(next);
38244
+ },
38245
+ subscribe: (listener) => {
38246
+ listeners.add(listener);
38247
+ return () => listeners.delete(listener);
38248
+ },
38249
+ };
38250
+ }
38251
+ function overlayStored(base, stored) {
38252
+ if (!stored) {
38253
+ return base;
38254
+ }
38255
+ const fromStored = mergeViewerOptions(stored);
38256
+ const merged = cloneOptions(base);
38257
+ const diff = diffViewerOptions(fromStored);
38258
+ for (const groupId of Object.keys(diff)) {
38259
+ const patch = diff[groupId];
38260
+ if (!patch) {
38261
+ continue;
38262
+ }
38263
+ Object.assign(merged[groupId], patch);
38264
+ }
38265
+ return merged;
38266
+ }
38267
+
37245
38268
  /**
37246
38269
  * Framework-agnostic rendering & editing helpers shared by the React, Vue, and
37247
38270
  * Angular `pptx-viewer` bindings. Pure TypeScript (no framework imports) — each
@@ -42580,6 +43603,192 @@ const translationsEn = {
42580
43603
  'pptx.connectorArrows.endLength': 'End Length',
42581
43604
  'pptx.slideThumbnail.transitionTooltip': 'Transition: {{name}}',
42582
43605
  'pptx.ribbon.groupShapeStyles': 'Shape Styles',
43606
+ 'pptx.options.title': 'Options',
43607
+ 'pptx.options.resetAll': 'Reset all options',
43608
+ 'pptx.options.resetTab': 'Reset this tab',
43609
+ 'pptx.options.general.description': 'General options for working with the viewer.',
43610
+ 'pptx.options.general.userInterface': 'User Interface options',
43611
+ 'pptx.options.general.displayOptimization': 'When using multiple displays',
43612
+ 'pptx.options.displayOptimization.appearance': 'Optimize for best appearance',
43613
+ 'pptx.options.displayOptimization.compatibility': 'Optimize for compatibility',
43614
+ 'pptx.options.general.showMiniToolbar': 'Show Mini Toolbar on selection',
43615
+ 'pptx.options.general.showMiniToolbarInfo': 'Shows the floating formatting toolbar when you select text.',
43616
+ 'pptx.options.general.enableLivePreview': 'Enable Live Preview',
43617
+ 'pptx.options.general.enableLivePreviewInfo': 'Previews formatting changes on the slide as you hover over gallery choices.',
43618
+ 'pptx.options.general.collapseRibbon': 'Collapse the ribbon automatically',
43619
+ 'pptx.options.general.collapseSearch': 'Collapse the search box by default',
43620
+ 'pptx.options.general.screenTipStyle': 'ScreenTip style',
43621
+ 'pptx.options.screenTipStyle.descriptions': 'Show feature descriptions in ScreenTips',
43622
+ 'pptx.options.screenTipStyle.plain': "Don't show feature descriptions in ScreenTips",
43623
+ 'pptx.options.screenTipStyle.off': "Don't show ScreenTips",
43624
+ 'pptx.options.general.personalize': 'Personalize your copy of the viewer',
43625
+ 'pptx.options.general.userName': 'User name',
43626
+ 'pptx.options.general.userInitials': 'Initials',
43627
+ 'pptx.options.general.appearance': 'Viewer theme',
43628
+ 'pptx.options.general.startup': 'Start up options',
43629
+ 'pptx.options.general.showStartScreen': 'Show the Start screen when this application starts',
43630
+ 'pptx.options.proofing.label': 'Proofing',
43631
+ 'pptx.options.proofing.description': 'Change how the viewer corrects and formats your text.',
43632
+ 'pptx.options.proofing.autoCorrect': 'AutoCorrect options',
43633
+ 'pptx.options.proofing.autoCorrectDescription': 'Change how text is corrected and formatted as you type.',
43634
+ 'pptx.options.proofing.twoInitialCapitals': 'Correct TWo INitial CApitals',
43635
+ 'pptx.options.proofing.capitalizeFirstLetter': 'Capitalize first letter of sentences',
43636
+ 'pptx.options.proofing.capitalizeDayNames': 'Capitalize names of days',
43637
+ 'pptx.options.proofing.smartQuotes': 'Replace straight quotes with smart quotes',
43638
+ 'pptx.options.proofing.hyphensToDash': 'Replace hyphens (--) with dash',
43639
+ 'pptx.options.proofing.fractions': 'Replace fractions (1/2) with fraction characters (½)',
43640
+ 'pptx.options.proofing.ordinals': 'Replace ordinals (1st) with superscript',
43641
+ 'pptx.options.proofing.spellingOffice': 'When correcting spelling',
43642
+ 'pptx.options.proofing.ignoreUppercase': 'Ignore words in UPPERCASE',
43643
+ 'pptx.options.proofing.ignoreWordsWithNumbers': 'Ignore words that contain numbers',
43644
+ 'pptx.options.proofing.ignoreInternetAddresses': 'Ignore Internet and file addresses',
43645
+ 'pptx.options.proofing.flagRepeatedWords': 'Flag repeated words',
43646
+ 'pptx.options.proofing.spellingViewer': 'When correcting spelling in the viewer',
43647
+ 'pptx.options.proofing.checkSpellingAsYouType': 'Check spelling as you type',
43648
+ 'pptx.options.proofing.hideSpellingErrors': 'Hide spelling errors',
43649
+ 'pptx.options.save.label': 'Save',
43650
+ 'pptx.options.save.description': 'Customize how documents are saved.',
43651
+ 'pptx.options.save.savePresentations': 'Save presentations',
43652
+ 'pptx.options.save.autoSave': 'Save changes automatically (AutoSave)',
43653
+ 'pptx.options.save.autoSaveInfo': 'Snapshots are stored locally and offered for recovery when you reopen.',
43654
+ 'pptx.options.save.defaultFormat': 'Save files in this format',
43655
+ 'pptx.options.saveFormat.pptx': 'PowerPoint Presentation (*.pptx)',
43656
+ 'pptx.options.saveFormat.pdf': 'PDF Document (*.pdf)',
43657
+ 'pptx.options.saveFormat.png': 'PNG Images (*.png)',
43658
+ 'pptx.options.save.autoRecoverInterval': 'Save AutoRecover information every',
43659
+ 'pptx.options.save.minutes': 'minutes',
43660
+ 'pptx.options.save.keepLastAutoRecovered': 'Keep the last AutoRecovered version if I close without saving',
43661
+ 'pptx.options.save.fidelity': 'Preserve fidelity when sharing this presentation',
43662
+ 'pptx.options.save.embedFonts': 'Embed fonts in the file',
43663
+ 'pptx.options.save.embedFontsInfo': 'Embedding fonts increases file size but keeps text identical on other devices.',
43664
+ 'pptx.options.save.embedAllCharacters': 'Embed all characters (best for editing by other people)',
43665
+ 'pptx.options.save.cache': 'Cache Settings',
43666
+ 'pptx.options.save.cacheRetentionDays': 'Days to keep files in the local document cache',
43667
+ 'pptx.options.save.days': 'days',
43668
+ 'pptx.options.save.clearCacheOnClose': 'Delete files from the local document cache when they are closed',
43669
+ 'pptx.options.save.clearCacheNow': 'Delete cached files',
43670
+ 'pptx.options.save.clearCacheDescription': 'Deletes locally stored recovery snapshots and recent files. This does not affect the open presentation.',
43671
+ 'pptx.options.language.description': 'Set the viewer language preferences.',
43672
+ 'pptx.options.language.displayLanguage': 'Display language',
43673
+ 'pptx.options.language.displayLanguageDescription': 'Buttons, menus, and other controls will show in the selected language.',
43674
+ 'pptx.options.accessibility.label': 'Accessibility',
43675
+ 'pptx.options.accessibility.description': 'Make the viewer more accessible.',
43676
+ 'pptx.options.accessibility.assistant': 'Make your document accessible to others',
43677
+ 'pptx.options.accessibility.showStatus': 'Show accessibility status in the status bar',
43678
+ 'pptx.options.accessibility.feedback': 'Feedback options',
43679
+ 'pptx.options.accessibility.feedbackWithSound': 'Provide feedback with sound',
43680
+ 'pptx.options.accessibility.soundScheme': 'Sound Scheme',
43681
+ 'pptx.options.soundScheme.modern': 'Modern',
43682
+ 'pptx.options.soundScheme.classic': 'Classic',
43683
+ 'pptx.options.accessibility.display': 'Application display options',
43684
+ 'pptx.options.accessibility.showShortcutKeys': 'Show shortcut keys in ScreenTips',
43685
+ 'pptx.options.advanced.label': 'Advanced',
43686
+ 'pptx.options.advanced.description': 'Advanced options for working with the viewer.',
43687
+ 'pptx.options.advanced.editing': 'Editing options',
43688
+ 'pptx.options.advanced.autoSelectWord': 'When selecting, automatically select entire word',
43689
+ 'pptx.options.advanced.textDragAndDrop': 'Allow text to be dragged and dropped',
43690
+ 'pptx.options.advanced.maximumUndoSteps': 'Maximum number of undos',
43691
+ 'pptx.options.advanced.cutCopyPaste': 'Cut, copy, and paste',
43692
+ 'pptx.options.advanced.smartCutAndPaste': 'Use smart cut and paste',
43693
+ 'pptx.options.advanced.showPasteOptions': 'Show Paste Options button when content is pasted',
43694
+ 'pptx.options.advanced.imageQuality': 'Image Size and Quality',
43695
+ 'pptx.options.advanced.doNotCompressImages': 'Do not compress images in file',
43696
+ 'pptx.options.advanced.defaultResolution': 'Default resolution',
43697
+ 'pptx.options.resolution.highFidelity': 'High fidelity',
43698
+ 'pptx.options.resolution.ppi330': '330 ppi',
43699
+ 'pptx.options.resolution.ppi220': '220 ppi',
43700
+ 'pptx.options.resolution.ppi150': '150 ppi',
43701
+ 'pptx.options.resolution.ppi96': '96 ppi',
43702
+ 'pptx.options.advanced.chart': 'Chart',
43703
+ 'pptx.options.advanced.chartFollowDataPoint': 'Properties follow chart data point',
43704
+ 'pptx.options.advanced.display': 'Display',
43705
+ 'pptx.options.advanced.recentCount': 'Show this number of Recent Presentations',
43706
+ 'pptx.options.advanced.disableHardwareAcceleration': 'Disable hardware graphics acceleration',
43707
+ 'pptx.options.advanced.openDocumentsView': 'Open all documents using this view',
43708
+ 'pptx.options.openView.savedView': 'The view saved in the file',
43709
+ 'pptx.options.openView.normal': 'Normal',
43710
+ 'pptx.options.openView.outline': 'Outline',
43711
+ 'pptx.options.openView.slideSorter': 'Slide Sorter',
43712
+ 'pptx.options.openView.notes': 'Notes',
43713
+ 'pptx.options.advanced.slideShow': 'Slide Show',
43714
+ 'pptx.options.advanced.showMenuOnRightClick': 'Show menu on right mouse click',
43715
+ 'pptx.options.advanced.showPopupToolbar': 'Show popup toolbar',
43716
+ 'pptx.options.advanced.promptKeepInk': 'Prompt to keep ink annotations when exiting',
43717
+ 'pptx.options.advanced.endWithBlackSlide': 'End with black slide',
43718
+ 'pptx.options.advanced.print': 'Print',
43719
+ 'pptx.options.advanced.printInBackground': 'Print in background',
43720
+ 'pptx.options.advanced.printHighQuality': 'High quality',
43721
+ 'pptx.options.advanced.printUseMostRecent': 'Use the most recently used print settings',
43722
+ 'pptx.options.advanced.printWhat': 'Print what',
43723
+ 'pptx.options.printWhat.slides': 'Full Page Slides',
43724
+ 'pptx.options.printWhat.handouts': 'Handouts',
43725
+ 'pptx.options.printWhat.notes': 'Notes Pages',
43726
+ 'pptx.options.printWhat.outline': 'Outline',
43727
+ 'pptx.options.advanced.printColorMode': 'Color/grayscale',
43728
+ 'pptx.options.printColorMode.color': 'Color',
43729
+ 'pptx.options.printColorMode.grayscale': 'Grayscale',
43730
+ 'pptx.options.printColorMode.blackAndWhite': 'Pure Black and White',
43731
+ 'pptx.options.advanced.printHiddenSlides': 'Print hidden slides',
43732
+ 'pptx.options.advanced.printScaleToFit': 'Scale to fit paper',
43733
+ 'pptx.options.advanced.printFrameSlides': 'Frame slides',
43734
+ 'pptx.options.ribbon.label': 'Customize Ribbon',
43735
+ 'pptx.options.ribbon.description': 'Customize the ribbon.',
43736
+ 'pptx.options.ribbon.tabsTitle': 'Main Tabs',
43737
+ 'pptx.options.ribbon.tabsDescription': 'Untick a tab to hide it from the ribbon. The File tab is always shown.',
43738
+ 'pptx.options.ribbon.reset': 'Reset ribbon customizations',
43739
+ 'pptx.options.quickAccess.label': 'Quick Access Toolbar',
43740
+ 'pptx.options.quickAccess.description': 'Customize the Quick Access Toolbar.',
43741
+ 'pptx.options.quickAccess.optionsTitle': 'Quick Access Toolbar options',
43742
+ 'pptx.options.quickAccess.show': 'Show Quick Access Toolbar',
43743
+ 'pptx.options.quickAccess.position': 'Toolbar Position',
43744
+ 'pptx.options.quickAccessPosition.above': 'Above Ribbon',
43745
+ 'pptx.options.quickAccessPosition.below': 'Below Ribbon',
43746
+ 'pptx.options.quickAccess.showLabels': 'Always show command labels',
43747
+ 'pptx.options.quickAccess.chooseCommands': 'Choose commands',
43748
+ 'pptx.options.quickAccess.currentCommands': 'Customize Quick Access Toolbar',
43749
+ 'pptx.options.quickAccess.add': 'Add',
43750
+ 'pptx.options.quickAccess.remove': 'Remove',
43751
+ 'pptx.options.quickAccess.moveUp': 'Move Up',
43752
+ 'pptx.options.quickAccess.moveDown': 'Move Down',
43753
+ 'pptx.options.quickAccess.reset': 'Reset',
43754
+ 'pptx.options.quickAccess.command.presentFromStart': 'From Beginning',
43755
+ 'pptx.options.quickAccess.command.print': 'Print',
43756
+ 'pptx.options.quickAccess.command.exportPdf': 'Export as PDF',
43757
+ 'pptx.options.quickAccess.command.newSlide': 'New Slide',
43758
+ 'pptx.options.quickAccess.command.zoomIn': 'Zoom In',
43759
+ 'pptx.options.quickAccess.command.zoomOut': 'Zoom Out',
43760
+ 'pptx.options.addIns.label': 'Add-ins',
43761
+ 'pptx.options.addIns.description': 'View and manage viewer capability modules.',
43762
+ 'pptx.options.addIns.name': 'Name',
43763
+ 'pptx.options.addIns.location': 'Location',
43764
+ 'pptx.options.addIns.type': 'Type',
43765
+ 'pptx.options.addIns.active': 'Active Capability Modules',
43766
+ 'pptx.options.addIns.inactive': 'Inactive Capability Modules',
43767
+ 'pptx.options.addInType.renderer': 'Renderer',
43768
+ 'pptx.options.addInType.converter': 'Converter',
43769
+ 'pptx.options.addInType.collaboration': 'Collaboration',
43770
+ 'pptx.options.addInType.localization': 'Localization',
43771
+ 'pptx.options.addIns.smartArt3d': 'SmartArt 3D Renderer',
43772
+ 'pptx.options.addIns.smartArt3dDescription': 'Opt-in three.js renderer for extruded and spatial SmartArt layouts.',
43773
+ 'pptx.options.addIns.model3d': '3D Model Renderer',
43774
+ 'pptx.options.addIns.model3dDescription': 'Interactive GLB/GLTF model rendering on slides.',
43775
+ 'pptx.options.addIns.emfConverter': 'EMF/WMF Converter',
43776
+ 'pptx.options.addIns.emfConverterDescription': 'Converts EMF and WMF metafile images to PNG for display.',
43777
+ 'pptx.options.addIns.mtxDecompressor': 'MicroType Express Font Decompressor',
43778
+ 'pptx.options.addIns.mtxDecompressorDescription': 'Decompresses embedded MicroType Express fonts.',
43779
+ 'pptx.options.addIns.collaboration': 'Real-time Collaboration',
43780
+ 'pptx.options.addIns.collaborationDescription': 'CRDT-based co-editing, presence, and sync relay support.',
43781
+ 'pptx.options.addIns.locales': 'Locale Packs',
43782
+ 'pptx.options.addIns.localesDescription': 'Additional display languages for the viewer chrome.',
43783
+ 'pptx.options.trust.label': 'Trust Center',
43784
+ 'pptx.options.trust.description': 'Help keep your documents safe and secure.',
43785
+ 'pptx.options.trust.settingsTitle': 'Security settings',
43786
+ 'pptx.options.trust.settingsDescription': 'These settings help keep the content you open safe. We recommend the defaults.',
43787
+ 'pptx.options.trust.protectedView': 'Open presentations in Protected View',
43788
+ 'pptx.options.trust.protectedViewInfo': 'Documents open read-only; use Enable Editing to make changes.',
43789
+ 'pptx.options.trust.allowExternalContent': 'Allow external content (remote images and media)',
43790
+ 'pptx.options.trust.allowExternalContentInfo': 'When off, only content embedded in the file is displayed.',
43791
+ 'pptx.options.trust.confirmHyperlinks': 'Confirm before opening external hyperlinks',
42583
43792
  };
42584
43793
  /**
42585
43794
  * Convert a dotted translation key to a human-readable label when no
@@ -44379,6 +45588,33 @@ class CollaborationService {
44379
45588
  seedBaseline(slides) {
44380
45589
  this.lastSynced = JSON.stringify(slides);
44381
45590
  }
45591
+ /**
45592
+ * Re-adopt the shared document's slides after a local content load has been
45593
+ * committed to viewer state. The load pipeline applies its parsed deck
45594
+ * unconditionally, so a load that finishes AFTER the room's slides were
45595
+ * already applied (a late joiner's bootstrap deck parsing slower than the
45596
+ * doc sync) silently clobbers the synced state and, with the doc itself
45597
+ * unchanged, the remote observer never re-fires. When the room already has
45598
+ * slides they win: the doc content is re-applied through `onRemoteSlides`
45599
+ * and recorded as the sync baseline (bypassing the usual JSON dedupe) so
45600
+ * the follow-up local broadcast of the adopted deck is a no-op. An empty
45601
+ * room means this client is the seeder and the loaded deck stands, written
45602
+ * by the normal gated broadcast path. Returns true when the doc was adopted.
45603
+ */
45604
+ adoptDocSlidesAfterLoad() {
45605
+ if (!this.ydoc || !this.connected()) {
45606
+ return false;
45607
+ }
45608
+ const docSlides = readSlidesFromYDoc(this.ydoc);
45609
+ if (docSlides.length === 0) {
45610
+ return false;
45611
+ }
45612
+ this.lastSynced = JSON.stringify(docSlides);
45613
+ this.applyingRemote = true;
45614
+ this.onRemoteSlides?.(docSlides);
45615
+ this.applyingRemote = false;
45616
+ return true;
45617
+ }
44382
45618
  broadcastSlides(slides) {
44383
45619
  if (!this.ydoc || !this.yFactories || this.applyingRemote || slides.length === 0) {
44384
45620
  return;
@@ -64582,6 +65818,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
64582
65818
  type: Injectable
64583
65819
  }] });
64584
65820
 
65821
+ /**
65822
+ * viewer-options.service.ts: signal-based owner of the File > Options store for
65823
+ * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
65824
+ *
65825
+ * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
65826
+ * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
65827
+ * Angular signal, and bundles the option-to-behavior helpers the rest of the
65828
+ * viewer consumes: history depth, autosave cadence, print defaults, screen
65829
+ * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
65830
+ * protected view, and the Options > Save cache purge.
65831
+ *
65832
+ * Deliberately constructible with plain `new` (no required injection context)
65833
+ * so the colocated unit tests can exercise it without TestBed, matching
65834
+ * {@link EditorStateService}'s optional-inject pattern.
65835
+ */
65836
+ class ViewerOptionsService {
65837
+ /**
65838
+ * Optional: `inject()` needs an active injection context, which plain
65839
+ * `new ViewerOptionsService()` (used by the colocated unit tests) does not
65840
+ * provide. Outside DI the subscription simply lives as long as the instance.
65841
+ */
65842
+ destroyRef = (() => {
65843
+ try {
65844
+ return inject(DestroyRef);
65845
+ }
65846
+ catch {
65847
+ return null;
65848
+ }
65849
+ })();
65850
+ translate = (() => {
65851
+ try {
65852
+ return inject(TranslateService);
65853
+ }
65854
+ catch {
65855
+ return null;
65856
+ }
65857
+ })();
65858
+ /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
65859
+ store = createViewerOptionsStore();
65860
+ _options = signal(this.store.getOptions(), /* @ts-ignore */
65861
+ ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
65862
+ /** Reactive File > Options snapshot; a new object per change. */
65863
+ options = this._options.asReadonly();
65864
+ constructor() {
65865
+ const unsubscribe = this.store.subscribe((next) => this._options.set(next));
65866
+ this.destroyRef?.onDestroy(unsubscribe);
65867
+ }
65868
+ // ── Store mutations ─────────────────────────────────────────────────────
65869
+ setValue(group, key, value) {
65870
+ this.store.setValue(group, key, value);
65871
+ }
65872
+ setRibbonTabHidden(tabId, hidden) {
65873
+ this.store.setRibbonTabHidden(tabId, hidden);
65874
+ }
65875
+ setQuickAccessCommands(commandIds) {
65876
+ this.store.setQuickAccessCommands(commandIds);
65877
+ }
65878
+ reset(group) {
65879
+ this.store.reset(group);
65880
+ }
65881
+ /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
65882
+ restore(snapshot) {
65883
+ this.store.setOptions(snapshot);
65884
+ }
65885
+ // ── Behavior resolution helpers ─────────────────────────────────────────
65886
+ /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
65887
+ historyDepth() {
65888
+ return resolveHistoryDepth(this.options());
65889
+ }
65890
+ /** AutoRecover cadence in seconds for the autosave engine. */
65891
+ autosaveIntervalSeconds() {
65892
+ return resolveAutosaveIntervalSeconds(this.options());
65893
+ }
65894
+ /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
65895
+ printDefaults() {
65896
+ return resolveDefaultPrintSettings(this.options());
65897
+ }
65898
+ /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
65899
+ rootClasses() {
65900
+ return resolveOptionRootClasses(this.options(), 'pptx-ng');
65901
+ }
65902
+ /** Tooltip text under the current ScreenTip style (undefined = suppress). */
65903
+ screenTip(label, description, shortcut) {
65904
+ return resolveScreenTip(this.options(), label, description, shortcut);
65905
+ }
65906
+ /** Run the enabled AutoCorrect rules over a committed run of text. */
65907
+ autoCorrect(text) {
65908
+ return applyAutoCorrect(text, this.options().proofing);
65909
+ }
65910
+ /** Play the Accessibility "feedback with sound" cue for a completed action. */
65911
+ playFeedback() {
65912
+ playFeedbackSound(this.options());
65913
+ }
65914
+ /** Whether Trust Center forces the deck to open read-only. */
65915
+ protectedView() {
65916
+ return shouldOpenInProtectedView(this.options());
65917
+ }
65918
+ /**
65919
+ * Gate an external hyperlink activation. Returns `true` when navigation may
65920
+ * proceed (no confirmation required, or the user confirmed the prompt).
65921
+ */
65922
+ confirmExternalHyperlink(href) {
65923
+ if (!shouldConfirmExternalHyperlink(this.options(), href)) {
65924
+ return true;
65925
+ }
65926
+ if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
65927
+ return true;
65928
+ }
65929
+ const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
65930
+ 'Confirm before opening external hyperlinks';
65931
+ return window.confirm(`${label}\n\n${href}`);
65932
+ }
65933
+ /**
65934
+ * Options > Save > "Delete cached files": purge every autosave recovery
65935
+ * snapshot from the shared IndexedDB store. Resolves with the purge count.
65936
+ */
65937
+ async clearCache() {
65938
+ const snapshots = await listAutosaveSnapshots();
65939
+ await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
65940
+ return snapshots.length;
65941
+ }
65942
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
65943
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService });
65944
+ }
65945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService, decorators: [{
65946
+ type: Injectable
65947
+ }], ctorParameters: () => [] });
65948
+
64585
65949
  /**
64586
65950
  * audience-content-store: IndexedDB-based storage for sharing PPTX content
64587
65951
  * between the presenter tab and audience tab.
@@ -65494,6 +66858,7 @@ const POWER_POINT_VIEWER_PROVIDERS = [
65494
66858
  ViewerInspectorPanelService,
65495
66859
  ViewerKeyboardService,
65496
66860
  ViewerMobileSheetService,
66861
+ ViewerOptionsService,
65497
66862
  ViewerPresentationModeService,
65498
66863
  ViewerThemeGalleryService,
65499
66864
  ViewerTouchGesturesService,
@@ -72505,7 +73870,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
72505
73870
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
72506
73871
 
72507
73872
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
72508
- const PPTX_ANGULAR_VIEWER_VERSION = "1.29.0";
73873
+ const PPTX_ANGULAR_VIEWER_VERSION = "1.30.1";
72509
73874
 
72510
73875
  /**
72511
73876
  * account-page.component.ts: File > Account content.
@@ -91018,10 +92383,15 @@ class TitleBarComponent {
91018
92383
  /** Toolbar buttons the host wants hidden (gates Undo/Redo independently). */
91019
92384
  hiddenActions = input([], /* @ts-ignore */
91020
92385
  ...(ngDevMode ? [{ debugName: "hiddenActions" }] : /* istanbul ignore next */ []));
92386
+ /** Live Quick Access Toolbar options (File > Options > Quick Access). */
92387
+ quickAccess = input(null, /* @ts-ignore */
92388
+ ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
91021
92389
  toggleAutosave = output();
91022
92390
  save = output();
91023
92391
  undo = output();
91024
92392
  redo = output();
92393
+ /** A configured Quick Access command was pressed (catalog id). */
92394
+ quickCommand = output();
91025
92395
  toggleFindReplace = output();
91026
92396
  commandSearch = output();
91027
92397
  translate = inject(TranslateService);
@@ -91032,6 +92402,41 @@ class TitleBarComponent {
91032
92402
  ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
91033
92403
  searchFocused = signal(false, /* @ts-ignore */
91034
92404
  ...(ngDevMode ? [{ debugName: "searchFocused" }] : /* istanbul ignore next */ []));
92405
+ /** Resolved Quick Access options (host-supplied, or the default trio+). */
92406
+ qat = computed(() => this.quickAccess() ?? DEFAULT_VIEWER_OPTIONS.quickAccess, /* @ts-ignore */
92407
+ ...(ngDevMode ? [{ debugName: "qat" }] : /* istanbul ignore next */ []));
92408
+ /**
92409
+ * Configured Quick Access commands beyond the dedicated save/undo/redo
92410
+ * buttons (which keep their own gating + labels). Rendered as text-label
92411
+ * buttons routed through {@link onQuickCommand}.
92412
+ */
92413
+ extraQuickCommands = computed(() => {
92414
+ const dedicated = new Set(['save', 'undo', 'redo']);
92415
+ return this.qat()
92416
+ .commandIds.filter((id) => !dedicated.has(id))
92417
+ .map((id) => QUICK_ACCESS_COMMAND_CATALOG.find((entry) => entry.id === id))
92418
+ .filter((entry) => entry !== undefined);
92419
+ }, /* @ts-ignore */
92420
+ ...(ngDevMode ? [{ debugName: "extraQuickCommands" }] : /* istanbul ignore next */ []));
92421
+ /**
92422
+ * Route a Quick Access press: keep the dedicated save/undo/redo outputs
92423
+ * (existing host wiring, `hiddenActions` gating) and forward everything
92424
+ * else through the generic {@link quickCommand} output.
92425
+ */
92426
+ onQuickCommand(id) {
92427
+ if (id === 'save') {
92428
+ this.save.emit();
92429
+ }
92430
+ else if (id === 'undo' && !this.toolbar.isHidden('undo')) {
92431
+ this.undo.emit();
92432
+ }
92433
+ else if (id === 'redo' && !this.toolbar.isHidden('redo')) {
92434
+ this.redo.emit();
92435
+ }
92436
+ else if (id !== 'undo' && id !== 'redo') {
92437
+ this.quickCommand.emit(id);
92438
+ }
92439
+ }
91035
92440
  commandResults = computed(() => filterCommands(this.searchQuery(), (key) => this.translate.instant(key)), /* @ts-ignore */
91036
92441
  ...(ngDevMode ? [{ debugName: "commandResults" }] : /* istanbul ignore next */ []));
91037
92442
  /** The i18n key for the save-location status text (next to the file name). */
@@ -91090,7 +92495,7 @@ class TitleBarComponent {
91090
92495
  }
91091
92496
  }
91092
92497
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TitleBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
91093
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TitleBarComponent, isStandalone: true, selector: "pptx-title-bar", inputs: { canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, isDirty: { classPropertyName: "isDirty", publicName: "isDirty", isSignal: true, isRequired: false, transformFunction: null }, autosaveStatus: { classPropertyName: "autosaveStatus", publicName: "autosaveStatus", isSignal: true, isRequired: false, transformFunction: null }, autosaveEnabled: { classPropertyName: "autosaveEnabled", publicName: "autosaveEnabled", isSignal: true, isRequired: false, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, undoLabel: { classPropertyName: "undoLabel", publicName: "undoLabel", isSignal: true, isRequired: false, transformFunction: null }, redoLabel: { classPropertyName: "redoLabel", publicName: "redoLabel", isSignal: true, isRequired: false, transformFunction: null }, findReplaceOpen: { classPropertyName: "findReplaceOpen", publicName: "findReplaceOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleAutosave: "toggleAutosave", save: "save", undo: "undo", redo: "redo", toggleFindReplace: "toggleFindReplace", commandSearch: "commandSearch" }, ngImport: i0, template: `
92498
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TitleBarComponent, isStandalone: true, selector: "pptx-title-bar", inputs: { canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, isDirty: { classPropertyName: "isDirty", publicName: "isDirty", isSignal: true, isRequired: false, transformFunction: null }, autosaveStatus: { classPropertyName: "autosaveStatus", publicName: "autosaveStatus", isSignal: true, isRequired: false, transformFunction: null }, autosaveEnabled: { classPropertyName: "autosaveEnabled", publicName: "autosaveEnabled", isSignal: true, isRequired: false, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, undoLabel: { classPropertyName: "undoLabel", publicName: "undoLabel", isSignal: true, isRequired: false, transformFunction: null }, redoLabel: { classPropertyName: "redoLabel", publicName: "redoLabel", isSignal: true, isRequired: false, transformFunction: null }, findReplaceOpen: { classPropertyName: "findReplaceOpen", publicName: "findReplaceOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleAutosave: "toggleAutosave", save: "save", undo: "undo", redo: "redo", quickCommand: "quickCommand", toggleFindReplace: "toggleFindReplace", commandSearch: "commandSearch" }, ngImport: i0, template: `
91094
92499
  <div [class]="tb.container" data-pptx-title-bar>
91095
92500
  <span [class]="tb.logo" aria-hidden="true">P</span>
91096
92501
 
@@ -91120,213 +92525,251 @@ class TitleBarComponent {
91120
92525
 
91121
92526
  <div [class]="tb.separator"></div>
91122
92527
 
91123
- <button
91124
- type="button"
91125
- [class]="tb.quickButton"
91126
- [title]="'pptx.titleBar.save' | translate"
91127
- [attr.aria-label]="'pptx.titleBar.save' | translate"
91128
- (click)="save.emit()"
91129
- >
91130
- <svg lucideSave class="h-3.5 w-3.5"></svg>
91131
- </button>
91132
- @if (!toolbar.isHidden('undo')) {
92528
+ @if (qat().visible) {
91133
92529
  <button
91134
92530
  type="button"
91135
92531
  [class]="tb.quickButton"
91136
- [disabled]="!canUndo()"
91137
- [title]="
91138
- undoLabel()
91139
- ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
91140
- : ('pptx.toolbar.undo' | translate)
91141
- "
91142
- [attr.aria-label]="'pptx.toolbar.undo' | translate"
91143
- (click)="undo.emit()"
92532
+ [title]="'pptx.titleBar.save' | translate"
92533
+ [attr.aria-label]="'pptx.titleBar.save' | translate"
92534
+ (click)="save.emit()"
91144
92535
  >
91145
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
92536
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
91146
92537
  </button>
91147
- }
91148
- @if (!toolbar.isHidden('redo')) {
91149
- <button
91150
- type="button"
91151
- [class]="tb.quickButton"
91152
- [disabled]="!canRedo()"
91153
- [title]="
91154
- redoLabel()
91155
- ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
91156
- : ('pptx.toolbar.redo' | translate)
91157
- "
91158
- [attr.aria-label]="'pptx.toolbar.redo' | translate"
91159
- (click)="redo.emit()"
91160
- >
91161
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
91162
- </button>
91163
- }
91164
-
91165
- <div [class]="tb.separator"></div>
91166
- }
91167
-
91168
- <span [class]="tb.fileGroup">
91169
- <span [class]="tb.fileName">{{ fileName() || (defaultFileKey | translate) }}</span>
91170
- @if (canEdit()) {
91171
- <span [class]="tb.statusDot" aria-hidden="true">&bull;</span>
91172
- <span [class]="tb.statusText" [ngClass]="statusStateClass()">{{
91173
- statusKey() | translate
91174
- }}</span>
91175
- }
91176
- </span>
91177
-
91178
- <span [class]="tb.searchWrap">
91179
- @if (canEdit()) {
91180
- <div class="relative w-full max-w-md">
91181
- <div
91182
- [class]="tb.searchBox"
91183
- [ngClass]="
91184
- searchFocused() || findReplaceOpen() ? 'text-foreground bg-background' : ''
92538
+ @if (!toolbar.isHidden('undo')) {
92539
+ <button
92540
+ type="button"
92541
+ [class]="tb.quickButton"
92542
+ [disabled]="!canUndo()"
92543
+ [title]="
92544
+ undoLabel()
92545
+ ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
92546
+ : ('pptx.toolbar.undo' | translate)
91185
92547
  "
92548
+ [attr.aria-label]="'pptx.toolbar.undo' | translate"
92549
+ (click)="undo.emit()"
91186
92550
  >
91187
- <span [class]="tb.searchIcon" aria-hidden="true"
91188
- ><svg lucideSearch class="h-3.5 w-3.5"></svg
91189
- ></span>
91190
- <input
91191
- type="text"
91192
- [value]="searchQuery()"
91193
- (input)="searchQuery.set($any($event.target).value)"
91194
- (focus)="searchFocused.set(true)"
91195
- (blur)="onSearchBlur()"
91196
- (keydown)="onSearchKeyDown($event)"
91197
- class="flex-1 bg-transparent text-[11px] outline-none placeholder:text-muted-foreground/60"
91198
- [placeholder]="'pptx.titleBar.searchPlaceholder' | translate"
91199
- [attr.aria-label]="'pptx.titleBar.search' | translate"
91200
- />
91201
- </div>
91202
- @if (searchFocused() && searchQuery().trim()) {
91203
- <div
91204
- class="absolute left-0 right-0 top-full z-50 mt-1 rounded-lg border border-border bg-popover shadow-xl max-h-64 overflow-y-auto"
91205
- >
91206
- @if (commandResults().length > 0) {
91207
- <div
91208
- class="px-3 py-1.5 text-[10px] font-semibold text-muted-foreground uppercase tracking-wider"
91209
- >
91210
- {{ 'pptx.titleBar.searchCommands' | translate }}
91211
- </div>
91212
- @for (entry of commandResults().slice(0, 8); track entry.command) {
91213
- <button
91214
- type="button"
91215
- class="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-foreground hover:bg-accent transition-colors"
91216
- (mousedown)="selectCommand(entry)"
91217
- >
91218
- <span class="truncate">{{ entry.labelKey | translate }}</span>
91219
- <span class="ml-auto text-[10px] text-muted-foreground capitalize">{{
91220
- entry.category
91221
- }}</span>
91222
- </button>
91223
- }
91224
- } @else {
91225
- <div class="px-3 py-2 text-xs text-muted-foreground">
91226
- {{ 'pptx.titleBar.searchNoResults' | translate }}
91227
- </div>
91228
- }
91229
- <div class="border-t border-border/60">
91230
- <button
91231
- type="button"
91232
- class="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-foreground hover:bg-accent transition-colors"
91233
- (mousedown)="openFindReplace()"
91234
- >
91235
- <svg lucideSearch class="h-3.5 w-3.5"></svg>
91236
- <span
91237
- >{{ 'pptx.titleBar.searchContent' | translate }} &ldquo;{{
91238
- searchQuery()
91239
- }}&rdquo;</span
91240
- >
91241
- </button>
91242
- </div>
91243
- </div>
91244
- }
91245
- </div>
91246
- }
91247
- </span>
91248
-
91249
- <span [class]="tb.rightSpacer"></span>
91250
- </div>
91251
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
91252
- }
91253
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TitleBarComponent, decorators: [{
91254
- type: Component,
91255
- args: [{
91256
- selector: 'pptx-title-bar',
91257
- standalone: true,
91258
- changeDetection: ChangeDetectionStrategy.OnPush,
91259
- imports: [NgClass, TranslatePipe, LucideSave, LucideUndo, LucideRedo, LucideSearch],
91260
- template: `
91261
- <div [class]="tb.container" data-pptx-title-bar>
91262
- <span [class]="tb.logo" aria-hidden="true">P</span>
91263
-
91264
- @if (canEdit()) {
91265
- <span [class]="tb.autosaveGroup">
91266
- <span [class]="tb.autosaveLabel">{{ 'pptx.titleBar.autoSave' | translate }}</span>
91267
- <button
91268
- type="button"
91269
- role="switch"
91270
- [attr.aria-checked]="autosaveEnabled()"
91271
- [class]="tb.toggleTrack"
91272
- [ngClass]="autosaveEnabled() ? tb.toggleTrackOn : tb.toggleTrackOff"
91273
- [title]="'pptx.titleBar.toggleAutoSave' | translate"
91274
- [attr.aria-label]="'pptx.titleBar.toggleAutoSave' | translate"
91275
- (click)="toggleAutosave.emit()"
91276
- >
91277
- <span
91278
- [class]="tb.toggleKnob"
91279
- [ngClass]="autosaveEnabled() ? tb.toggleKnobOn : tb.toggleKnobOff"
91280
- ></span>
91281
- </button>
91282
- <span [class]="tb.autosaveLabel">{{
91283
- (autosaveEnabled() ? 'pptx.titleBar.autoSaveOn' : 'pptx.titleBar.autoSaveOff')
91284
- | translate
91285
- }}</span>
91286
- </span>
91287
-
91288
- <div [class]="tb.separator"></div>
91289
-
91290
- <button
91291
- type="button"
91292
- [class]="tb.quickButton"
91293
- [title]="'pptx.titleBar.save' | translate"
91294
- [attr.aria-label]="'pptx.titleBar.save' | translate"
91295
- (click)="save.emit()"
91296
- >
91297
- <svg lucideSave class="h-3.5 w-3.5"></svg>
91298
- </button>
91299
- @if (!toolbar.isHidden('undo')) {
91300
- <button
91301
- type="button"
91302
- [class]="tb.quickButton"
91303
- [disabled]="!canUndo()"
91304
- [title]="
91305
- undoLabel()
91306
- ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
91307
- : ('pptx.toolbar.undo' | translate)
91308
- "
91309
- [attr.aria-label]="'pptx.toolbar.undo' | translate"
91310
- (click)="undo.emit()"
91311
- >
91312
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
91313
- </button>
91314
- }
91315
- @if (!toolbar.isHidden('redo')) {
91316
- <button
91317
- type="button"
91318
- [class]="tb.quickButton"
91319
- [disabled]="!canRedo()"
91320
- [title]="
91321
- redoLabel()
91322
- ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
91323
- : ('pptx.toolbar.redo' | translate)
91324
- "
91325
- [attr.aria-label]="'pptx.toolbar.redo' | translate"
91326
- (click)="redo.emit()"
91327
- >
91328
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
91329
- </button>
92551
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
92552
+ </button>
92553
+ }
92554
+ @if (!toolbar.isHidden('redo')) {
92555
+ <button
92556
+ type="button"
92557
+ [class]="tb.quickButton"
92558
+ [disabled]="!canRedo()"
92559
+ [title]="
92560
+ redoLabel()
92561
+ ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
92562
+ : ('pptx.toolbar.redo' | translate)
92563
+ "
92564
+ [attr.aria-label]="'pptx.toolbar.redo' | translate"
92565
+ (click)="redo.emit()"
92566
+ >
92567
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
92568
+ </button>
92569
+ }
92570
+ @for (cmd of extraQuickCommands(); track cmd.id) {
92571
+ <button
92572
+ type="button"
92573
+ [class]="tb.quickButton"
92574
+ [title]="cmd.labelKey | translate"
92575
+ [attr.aria-label]="cmd.labelKey | translate"
92576
+ (click)="onQuickCommand(cmd.id)"
92577
+ >
92578
+ @if (qat().showCommandLabels) {
92579
+ <span class="text-[11px]">{{ cmd.labelKey | translate }}</span>
92580
+ } @else {
92581
+ <span class="text-[11px] font-semibold" aria-hidden="true">{{
92582
+ (cmd.labelKey | translate).charAt(0)
92583
+ }}</span>
92584
+ }
92585
+ </button>
92586
+ }
92587
+ }
92588
+
92589
+ <div [class]="tb.separator"></div>
92590
+ }
92591
+
92592
+ <span [class]="tb.fileGroup">
92593
+ <span [class]="tb.fileName">{{ fileName() || (defaultFileKey | translate) }}</span>
92594
+ @if (canEdit()) {
92595
+ <span [class]="tb.statusDot" aria-hidden="true">&bull;</span>
92596
+ <span [class]="tb.statusText" [ngClass]="statusStateClass()">{{
92597
+ statusKey() | translate
92598
+ }}</span>
92599
+ }
92600
+ </span>
92601
+
92602
+ <span [class]="tb.searchWrap">
92603
+ @if (canEdit()) {
92604
+ <div class="relative w-full max-w-md">
92605
+ <div
92606
+ [class]="tb.searchBox"
92607
+ [ngClass]="
92608
+ searchFocused() || findReplaceOpen() ? 'text-foreground bg-background' : ''
92609
+ "
92610
+ >
92611
+ <span [class]="tb.searchIcon" aria-hidden="true"
92612
+ ><svg lucideSearch class="h-3.5 w-3.5"></svg
92613
+ ></span>
92614
+ <input
92615
+ type="text"
92616
+ [value]="searchQuery()"
92617
+ (input)="searchQuery.set($any($event.target).value)"
92618
+ (focus)="searchFocused.set(true)"
92619
+ (blur)="onSearchBlur()"
92620
+ (keydown)="onSearchKeyDown($event)"
92621
+ class="flex-1 bg-transparent text-[11px] outline-none placeholder:text-muted-foreground/60"
92622
+ [placeholder]="'pptx.titleBar.searchPlaceholder' | translate"
92623
+ [attr.aria-label]="'pptx.titleBar.search' | translate"
92624
+ />
92625
+ </div>
92626
+ @if (searchFocused() && searchQuery().trim()) {
92627
+ <div
92628
+ class="absolute left-0 right-0 top-full z-50 mt-1 rounded-lg border border-border bg-popover shadow-xl max-h-64 overflow-y-auto"
92629
+ >
92630
+ @if (commandResults().length > 0) {
92631
+ <div
92632
+ class="px-3 py-1.5 text-[10px] font-semibold text-muted-foreground uppercase tracking-wider"
92633
+ >
92634
+ {{ 'pptx.titleBar.searchCommands' | translate }}
92635
+ </div>
92636
+ @for (entry of commandResults().slice(0, 8); track entry.command) {
92637
+ <button
92638
+ type="button"
92639
+ class="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-foreground hover:bg-accent transition-colors"
92640
+ (mousedown)="selectCommand(entry)"
92641
+ >
92642
+ <span class="truncate">{{ entry.labelKey | translate }}</span>
92643
+ <span class="ml-auto text-[10px] text-muted-foreground capitalize">{{
92644
+ entry.category
92645
+ }}</span>
92646
+ </button>
92647
+ }
92648
+ } @else {
92649
+ <div class="px-3 py-2 text-xs text-muted-foreground">
92650
+ {{ 'pptx.titleBar.searchNoResults' | translate }}
92651
+ </div>
92652
+ }
92653
+ <div class="border-t border-border/60">
92654
+ <button
92655
+ type="button"
92656
+ class="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-foreground hover:bg-accent transition-colors"
92657
+ (mousedown)="openFindReplace()"
92658
+ >
92659
+ <svg lucideSearch class="h-3.5 w-3.5"></svg>
92660
+ <span
92661
+ >{{ 'pptx.titleBar.searchContent' | translate }} &ldquo;{{
92662
+ searchQuery()
92663
+ }}&rdquo;</span
92664
+ >
92665
+ </button>
92666
+ </div>
92667
+ </div>
92668
+ }
92669
+ </div>
92670
+ }
92671
+ </span>
92672
+
92673
+ <span [class]="tb.rightSpacer"></span>
92674
+ </div>
92675
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
92676
+ }
92677
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TitleBarComponent, decorators: [{
92678
+ type: Component,
92679
+ args: [{
92680
+ selector: 'pptx-title-bar',
92681
+ standalone: true,
92682
+ changeDetection: ChangeDetectionStrategy.OnPush,
92683
+ imports: [NgClass, TranslatePipe, LucideSave, LucideUndo, LucideRedo, LucideSearch],
92684
+ template: `
92685
+ <div [class]="tb.container" data-pptx-title-bar>
92686
+ <span [class]="tb.logo" aria-hidden="true">P</span>
92687
+
92688
+ @if (canEdit()) {
92689
+ <span [class]="tb.autosaveGroup">
92690
+ <span [class]="tb.autosaveLabel">{{ 'pptx.titleBar.autoSave' | translate }}</span>
92691
+ <button
92692
+ type="button"
92693
+ role="switch"
92694
+ [attr.aria-checked]="autosaveEnabled()"
92695
+ [class]="tb.toggleTrack"
92696
+ [ngClass]="autosaveEnabled() ? tb.toggleTrackOn : tb.toggleTrackOff"
92697
+ [title]="'pptx.titleBar.toggleAutoSave' | translate"
92698
+ [attr.aria-label]="'pptx.titleBar.toggleAutoSave' | translate"
92699
+ (click)="toggleAutosave.emit()"
92700
+ >
92701
+ <span
92702
+ [class]="tb.toggleKnob"
92703
+ [ngClass]="autosaveEnabled() ? tb.toggleKnobOn : tb.toggleKnobOff"
92704
+ ></span>
92705
+ </button>
92706
+ <span [class]="tb.autosaveLabel">{{
92707
+ (autosaveEnabled() ? 'pptx.titleBar.autoSaveOn' : 'pptx.titleBar.autoSaveOff')
92708
+ | translate
92709
+ }}</span>
92710
+ </span>
92711
+
92712
+ <div [class]="tb.separator"></div>
92713
+
92714
+ @if (qat().visible) {
92715
+ <button
92716
+ type="button"
92717
+ [class]="tb.quickButton"
92718
+ [title]="'pptx.titleBar.save' | translate"
92719
+ [attr.aria-label]="'pptx.titleBar.save' | translate"
92720
+ (click)="save.emit()"
92721
+ >
92722
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
92723
+ </button>
92724
+ @if (!toolbar.isHidden('undo')) {
92725
+ <button
92726
+ type="button"
92727
+ [class]="tb.quickButton"
92728
+ [disabled]="!canUndo()"
92729
+ [title]="
92730
+ undoLabel()
92731
+ ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
92732
+ : ('pptx.toolbar.undo' | translate)
92733
+ "
92734
+ [attr.aria-label]="'pptx.toolbar.undo' | translate"
92735
+ (click)="undo.emit()"
92736
+ >
92737
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
92738
+ </button>
92739
+ }
92740
+ @if (!toolbar.isHidden('redo')) {
92741
+ <button
92742
+ type="button"
92743
+ [class]="tb.quickButton"
92744
+ [disabled]="!canRedo()"
92745
+ [title]="
92746
+ redoLabel()
92747
+ ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
92748
+ : ('pptx.toolbar.redo' | translate)
92749
+ "
92750
+ [attr.aria-label]="'pptx.toolbar.redo' | translate"
92751
+ (click)="redo.emit()"
92752
+ >
92753
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
92754
+ </button>
92755
+ }
92756
+ @for (cmd of extraQuickCommands(); track cmd.id) {
92757
+ <button
92758
+ type="button"
92759
+ [class]="tb.quickButton"
92760
+ [title]="cmd.labelKey | translate"
92761
+ [attr.aria-label]="cmd.labelKey | translate"
92762
+ (click)="onQuickCommand(cmd.id)"
92763
+ >
92764
+ @if (qat().showCommandLabels) {
92765
+ <span class="text-[11px]">{{ cmd.labelKey | translate }}</span>
92766
+ } @else {
92767
+ <span class="text-[11px] font-semibold" aria-hidden="true">{{
92768
+ (cmd.labelKey | translate).charAt(0)
92769
+ }}</span>
92770
+ }
92771
+ </button>
92772
+ }
91330
92773
  }
91331
92774
 
91332
92775
  <div [class]="tb.separator"></div>
@@ -91417,7 +92860,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
91417
92860
  </div>
91418
92861
  `,
91419
92862
  }]
91420
- }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], isDirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDirty", required: false }] }], autosaveStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveStatus", required: false }] }], autosaveEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveEnabled", required: false }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], undoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoLabel", required: false }] }], redoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "redoLabel", required: false }] }], findReplaceOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findReplaceOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], toggleAutosave: [{ type: i0.Output, args: ["toggleAutosave"] }], save: [{ type: i0.Output, args: ["save"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], toggleFindReplace: [{ type: i0.Output, args: ["toggleFindReplace"] }], commandSearch: [{ type: i0.Output, args: ["commandSearch"] }] } });
92863
+ }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], isDirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDirty", required: false }] }], autosaveStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveStatus", required: false }] }], autosaveEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveEnabled", required: false }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], undoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoLabel", required: false }] }], redoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "redoLabel", required: false }] }], findReplaceOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findReplaceOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: false }] }], toggleAutosave: [{ type: i0.Output, args: ["toggleAutosave"] }], save: [{ type: i0.Output, args: ["save"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], quickCommand: [{ type: i0.Output, args: ["quickCommand"] }], toggleFindReplace: [{ type: i0.Output, args: ["toggleFindReplace"] }], commandSearch: [{ type: i0.Output, args: ["commandSearch"] }] } });
91421
92864
 
91422
92865
  /**
91423
92866
  * slide-diff-helpers.ts: Pure label / icon helpers for the slide-diff row and
@@ -94080,6 +95523,728 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
94080
95523
  `, styles: [".pptx-ng-sss-body{display:flex;flex-direction:column;gap:1.25rem;font-size:.75rem;color:var(--pptx-foreground, #f3f4f6)}.pptx-ng-sss-fieldset{display:flex;flex-direction:column;gap:.375rem;margin:0;padding:0;border:none}.pptx-ng-sss-legend{margin-bottom:.25rem;padding:0;font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-sss-option{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:var(--pptx-foreground, #f3f4f6);cursor:pointer}.pptx-ng-sss-radio{accent-color:var(--pptx-primary, #6366f1)}.pptx-ng-sss-btn{padding:.375rem .75rem;border:1px solid var(--pptx-border, #374151);border-radius:.375rem;background:var(--pptx-card, #111827);color:var(--pptx-foreground, #f3f4f6);font-size:.75rem;cursor:pointer;white-space:nowrap;transition:background .15s ease}.pptx-ng-sss-btn:hover{background:var(--pptx-border, #374151)}.pptx-ng-sss-btn-primary{border-color:var(--pptx-primary, #6366f1);background:var(--pptx-primary, #6366f1);color:#fff}.pptx-ng-sss-btn-primary:hover{background:var(--pptx-primary, #6366f1);filter:brightness(1.1)}\n"] }]
94081
95524
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], save: [{ type: i0.Output, args: ["save"] }], close: [{ type: i0.Output, args: ["close"] }] } });
94082
95525
 
95526
+ /**
95527
+ * options-add-ins-pane.component.ts: Options > Add-ins pane (Angular port of
95528
+ * React's `settings/OptionsAddInsPane.tsx`).
95529
+ *
95530
+ * Presents the viewer's optional capability modules the way PowerPoint lists
95531
+ * COM add-ins: a name/location/type table grouped by active state (from
95532
+ * host-supplied {@link ViewerAddinStatus} flags; unset ids default to active),
95533
+ * with a detail card for the selected row.
95534
+ */
95535
+ class OptionsAddInsPaneComponent {
95536
+ /** Host-supplied availability flags; unset ids default to active. */
95537
+ addinStatus = input(undefined, /* @ts-ignore */
95538
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
95539
+ selectedId = signal(null, /* @ts-ignore */
95540
+ ...(ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []));
95541
+ rows = computed(() => resolveViewerAddinRows(this.addinStatus()), /* @ts-ignore */
95542
+ ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
95543
+ active = computed(() => this.rows().filter((row) => row.active), /* @ts-ignore */
95544
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
95545
+ inactive = computed(() => this.rows().filter((row) => !row.active), /* @ts-ignore */
95546
+ ...(ngDevMode ? [{ debugName: "inactive" }] : /* istanbul ignore next */ []));
95547
+ selected = computed(() => this.rows().find((row) => row.id === this.selectedId()) ?? null, /* @ts-ignore */
95548
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
95549
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsAddInsPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95550
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsAddInsPaneComponent, isStandalone: true, selector: "pptx-options-add-ins-pane", inputs: { addinStatus: { classPropertyName: "addinStatus", publicName: "addinStatus", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
95551
+ <div class="pptx-ng-options-addins">
95552
+ <div class="pptx-ng-options-addins-head">
95553
+ <span>{{ 'pptx.options.addIns.name' | translate }}</span>
95554
+ <span>{{ 'pptx.options.addIns.location' | translate }}</span>
95555
+ <span>{{ 'pptx.options.addIns.type' | translate }}</span>
95556
+ </div>
95557
+
95558
+ <section>
95559
+ <h4>{{ 'pptx.options.addIns.active' | translate }}</h4>
95560
+ @for (row of active(); track row.id) {
95561
+ <button
95562
+ type="button"
95563
+ class="pptx-ng-options-addins-row"
95564
+ [class.is-selected]="selectedId() === row.id"
95565
+ (click)="selectedId.set(row.id)"
95566
+ >
95567
+ <span>{{ row.nameKey | translate }}</span>
95568
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95569
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95570
+ </button>
95571
+ } @empty {
95572
+ <p class="pptx-ng-options-addins-empty">
95573
+ {{ 'pptx.options.addIns.description' | translate }}
95574
+ </p>
95575
+ }
95576
+ </section>
95577
+
95578
+ <section>
95579
+ <h4>{{ 'pptx.options.addIns.inactive' | translate }}</h4>
95580
+ @for (row of inactive(); track row.id) {
95581
+ <button
95582
+ type="button"
95583
+ class="pptx-ng-options-addins-row"
95584
+ [class.is-selected]="selectedId() === row.id"
95585
+ (click)="selectedId.set(row.id)"
95586
+ >
95587
+ <span>{{ row.nameKey | translate }}</span>
95588
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95589
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95590
+ </button>
95591
+ } @empty {
95592
+ <p class="pptx-ng-options-addins-empty">
95593
+ {{ 'pptx.options.addIns.description' | translate }}
95594
+ </p>
95595
+ }
95596
+ </section>
95597
+
95598
+ @if (selected(); as row) {
95599
+ <div class="pptx-ng-options-addins-detail">
95600
+ <p class="pptx-ng-options-addins-detail-name">{{ row.nameKey | translate }}</p>
95601
+ <p>{{ row.descriptionKey | translate }}</p>
95602
+ <p class="pptx-ng-options-addins-loc">{{ row.location }}</p>
95603
+ </div>
95604
+ }
95605
+ </div>
95606
+ `, isInline: true, styles: [".pptx-ng-options-addins{display:flex;flex-direction:column;gap:14px}.pptx-ng-options-addins-head,.pptx-ng-options-addins-row{display:grid;grid-template-columns:1.4fr 1fr .7fr;gap:8px;align-items:center}.pptx-ng-options-addins-head{padding:0 8px 4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-addins h4{margin:0 0 2px;font-size:12px;font-weight:600}.pptx-ng-options-addins-row{width:100%;padding:6px 8px;border:0;border-bottom:1px solid color-mix(in srgb,var(--pptx-border) 45%,transparent);background:transparent;color:var(--pptx-foreground);font-size:12px;text-align:left;cursor:pointer}.pptx-ng-options-addins-row:hover{background:var(--pptx-accent)}.pptx-ng-options-addins-row.is-selected{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent)}.pptx-ng-options-addins-loc{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;overflow-wrap:anywhere}.pptx-ng-options-addins-empty{margin:0;padding:4px 8px;color:var(--pptx-muted-foreground);font-size:11px;font-style:italic}.pptx-ng-options-addins-detail{padding:10px 12px;border:1px solid var(--pptx-border);border-radius:6px;background:var(--pptx-muted);font-size:12px}.pptx-ng-options-addins-detail p{margin:0 0 4px}.pptx-ng-options-addins-detail-name{font-weight:600}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95607
+ }
95608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsAddInsPaneComponent, decorators: [{
95609
+ type: Component,
95610
+ args: [{ selector: 'pptx-options-add-ins-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
95611
+ <div class="pptx-ng-options-addins">
95612
+ <div class="pptx-ng-options-addins-head">
95613
+ <span>{{ 'pptx.options.addIns.name' | translate }}</span>
95614
+ <span>{{ 'pptx.options.addIns.location' | translate }}</span>
95615
+ <span>{{ 'pptx.options.addIns.type' | translate }}</span>
95616
+ </div>
95617
+
95618
+ <section>
95619
+ <h4>{{ 'pptx.options.addIns.active' | translate }}</h4>
95620
+ @for (row of active(); track row.id) {
95621
+ <button
95622
+ type="button"
95623
+ class="pptx-ng-options-addins-row"
95624
+ [class.is-selected]="selectedId() === row.id"
95625
+ (click)="selectedId.set(row.id)"
95626
+ >
95627
+ <span>{{ row.nameKey | translate }}</span>
95628
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95629
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95630
+ </button>
95631
+ } @empty {
95632
+ <p class="pptx-ng-options-addins-empty">
95633
+ {{ 'pptx.options.addIns.description' | translate }}
95634
+ </p>
95635
+ }
95636
+ </section>
95637
+
95638
+ <section>
95639
+ <h4>{{ 'pptx.options.addIns.inactive' | translate }}</h4>
95640
+ @for (row of inactive(); track row.id) {
95641
+ <button
95642
+ type="button"
95643
+ class="pptx-ng-options-addins-row"
95644
+ [class.is-selected]="selectedId() === row.id"
95645
+ (click)="selectedId.set(row.id)"
95646
+ >
95647
+ <span>{{ row.nameKey | translate }}</span>
95648
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95649
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95650
+ </button>
95651
+ } @empty {
95652
+ <p class="pptx-ng-options-addins-empty">
95653
+ {{ 'pptx.options.addIns.description' | translate }}
95654
+ </p>
95655
+ }
95656
+ </section>
95657
+
95658
+ @if (selected(); as row) {
95659
+ <div class="pptx-ng-options-addins-detail">
95660
+ <p class="pptx-ng-options-addins-detail-name">{{ row.nameKey | translate }}</p>
95661
+ <p>{{ row.descriptionKey | translate }}</p>
95662
+ <p class="pptx-ng-options-addins-loc">{{ row.location }}</p>
95663
+ </div>
95664
+ }
95665
+ </div>
95666
+ `, styles: [".pptx-ng-options-addins{display:flex;flex-direction:column;gap:14px}.pptx-ng-options-addins-head,.pptx-ng-options-addins-row{display:grid;grid-template-columns:1.4fr 1fr .7fr;gap:8px;align-items:center}.pptx-ng-options-addins-head{padding:0 8px 4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-addins h4{margin:0 0 2px;font-size:12px;font-weight:600}.pptx-ng-options-addins-row{width:100%;padding:6px 8px;border:0;border-bottom:1px solid color-mix(in srgb,var(--pptx-border) 45%,transparent);background:transparent;color:var(--pptx-foreground);font-size:12px;text-align:left;cursor:pointer}.pptx-ng-options-addins-row:hover{background:var(--pptx-accent)}.pptx-ng-options-addins-row.is-selected{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent)}.pptx-ng-options-addins-loc{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;overflow-wrap:anywhere}.pptx-ng-options-addins-empty{margin:0;padding:4px 8px;color:var(--pptx-muted-foreground);font-size:11px;font-style:italic}.pptx-ng-options-addins-detail{padding:10px 12px;border:1px solid var(--pptx-border);border-radius:6px;background:var(--pptx-muted);font-size:12px}.pptx-ng-options-addins-detail p{margin:0 0 4px}.pptx-ng-options-addins-detail-name{font-weight:600}\n"] }]
95667
+ }], propDecorators: { addinStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "addinStatus", required: false }] }] } });
95668
+
95669
+ /**
95670
+ * options-pane.component.ts: generic, schema-driven File > Options pane
95671
+ * (Angular port of React's `settings/OptionsPane.tsx`).
95672
+ *
95673
+ * Renders one {@link ViewerOptionsTabDefinition}: the headline, then each
95674
+ * section's toggle/select/number/text controls with optional "(i)" info
95675
+ * tooltips and PowerPoint-style indenting. Bespoke blocks are handled via
95676
+ * `special`: `clearCache` renders inline (emitting {@link clearCache}), and
95677
+ * `themePicker` projects host content marked `themePicker` (the appearance
95678
+ * swatch gallery). Extra custom content (the Quick Access chooser) projects
95679
+ * after the sections.
95680
+ */
95681
+ /** Read a control's current primitive value off the options snapshot. */
95682
+ function readOptionValue(options, control) {
95683
+ const group = options[control.group];
95684
+ const value = group[control.key];
95685
+ return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'
95686
+ ? value
95687
+ : undefined;
95688
+ }
95689
+ /** Clamp a number-control edit into its schema range (NaN falls to min). */
95690
+ function clampOptionNumber(raw, min, max) {
95691
+ const parsed = Number(raw);
95692
+ if (!Number.isFinite(parsed)) {
95693
+ return min;
95694
+ }
95695
+ return Math.min(max, Math.max(min, parsed));
95696
+ }
95697
+ class OptionsPaneComponent {
95698
+ tab = input.required(/* @ts-ignore */
95699
+ ...(ngDevMode ? [{ debugName: "tab" }] : /* istanbul ignore next */ []));
95700
+ options = input.required(/* @ts-ignore */
95701
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
95702
+ /** One control edited (applied live by the host). */
95703
+ valueChange = output();
95704
+ /** Options > Save > "Delete cached files" pressed. */
95705
+ clearCache = output();
95706
+ value(control) {
95707
+ return readOptionValue(this.options(), control);
95708
+ }
95709
+ selectChoices(control) {
95710
+ return control.kind === 'select' ? control.choices : [];
95711
+ }
95712
+ numberMin(control) {
95713
+ return control.kind === 'number' ? control.min : 0;
95714
+ }
95715
+ numberMax(control) {
95716
+ return control.kind === 'number' ? control.max : 0;
95717
+ }
95718
+ numberUnitKey(control) {
95719
+ return control.kind === 'number' ? control.unitKey : undefined;
95720
+ }
95721
+ emitToggle(control, event) {
95722
+ this.emit(control, event.target.checked);
95723
+ }
95724
+ emitSelect(control, event) {
95725
+ this.emit(control, event.target.value);
95726
+ }
95727
+ emitNumber(control, event) {
95728
+ if (control.kind !== 'number') {
95729
+ return;
95730
+ }
95731
+ const raw = event.target.value;
95732
+ this.emit(control, clampOptionNumber(raw, control.min, control.max));
95733
+ }
95734
+ emitText(control, event) {
95735
+ this.emit(control, event.target.value);
95736
+ }
95737
+ emit(control, value) {
95738
+ this.valueChange.emit({ group: control.group, key: control.key, value });
95739
+ }
95740
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95741
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsPaneComponent, isStandalone: true, selector: "pptx-options-pane", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange", clearCache: "clearCache" }, ngImport: i0, template: `
95742
+ <div class="pptx-ng-options-pane">
95743
+ <p class="pptx-ng-options-headline">{{ tab().descriptionKey | translate }}</p>
95744
+ @for (section of tab().sections; track section.id) {
95745
+ <section class="pptx-ng-options-section">
95746
+ <h3>{{ section.titleKey | translate }}</h3>
95747
+ @if (section.descriptionKey; as descriptionKey) {
95748
+ <p class="pptx-ng-options-note">{{ descriptionKey | translate }}</p>
95749
+ }
95750
+ @for (control of section.controls; track control.group + '.' + control.key) {
95751
+ <div class="pptx-ng-options-row" [class.is-indented]="control.indent">
95752
+ <span class="pptx-ng-options-label">
95753
+ {{ control.labelKey | translate }}
95754
+ @if (control.infoKey; as infoKey) {
95755
+ <span
95756
+ class="pptx-ng-options-info"
95757
+ [title]="infoKey | translate"
95758
+ aria-hidden="true"
95759
+ >&#9432;</span
95760
+ >
95761
+ }
95762
+ </span>
95763
+ @switch (control.kind) {
95764
+ @case ('toggle') {
95765
+ <input
95766
+ type="checkbox"
95767
+ class="pptx-ng-options-check"
95768
+ [checked]="value(control) === true"
95769
+ [attr.aria-label]="control.labelKey | translate"
95770
+ (change)="emitToggle(control, $event)"
95771
+ />
95772
+ }
95773
+ @case ('select') {
95774
+ <select
95775
+ class="pptx-ng-options-select"
95776
+ [value]="value(control)"
95777
+ [attr.aria-label]="control.labelKey | translate"
95778
+ (change)="emitSelect(control, $event)"
95779
+ >
95780
+ @for (choice of selectChoices(control); track choice.value) {
95781
+ <option [value]="choice.value" [selected]="choice.value === value(control)">
95782
+ {{ choice.labelKey | translate }}
95783
+ </option>
95784
+ }
95785
+ </select>
95786
+ }
95787
+ @case ('number') {
95788
+ <span class="pptx-ng-options-number">
95789
+ <input
95790
+ type="number"
95791
+ [min]="numberMin(control)"
95792
+ [max]="numberMax(control)"
95793
+ [value]="value(control)"
95794
+ [attr.aria-label]="control.labelKey | translate"
95795
+ (change)="emitNumber(control, $event)"
95796
+ />
95797
+ @if (numberUnitKey(control); as unitKey) {
95798
+ <span class="pptx-ng-options-note">{{ unitKey | translate }}</span>
95799
+ }
95800
+ </span>
95801
+ }
95802
+ @default {
95803
+ <input
95804
+ type="text"
95805
+ class="pptx-ng-options-text"
95806
+ maxlength="64"
95807
+ [value]="value(control) ?? ''"
95808
+ [attr.aria-label]="control.labelKey | translate"
95809
+ (change)="emitText(control, $event)"
95810
+ />
95811
+ }
95812
+ }
95813
+ </div>
95814
+ }
95815
+ @if (section.special === 'themePicker') {
95816
+ <ng-content select="[themePicker]" />
95817
+ } @else if (section.special === 'clearCache') {
95818
+ <p class="pptx-ng-options-note">
95819
+ {{ 'pptx.options.save.clearCacheDescription' | translate }}
95820
+ </p>
95821
+ <button type="button" class="pptx-ng-options-btn" (click)="clearCache.emit()">
95822
+ {{ 'pptx.options.save.clearCacheNow' | translate }}
95823
+ </button>
95824
+ }
95825
+ </section>
95826
+ }
95827
+ <ng-content />
95828
+ </div>
95829
+ `, isInline: true, styles: [".pptx-ng-options-pane{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-headline{margin:0;font-size:13px;font-weight:600}.pptx-ng-options-section h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:5px 0;font-size:13px}.pptx-ng-options-row.is-indented{padding-left:22px}.pptx-ng-options-info{margin-left:4px;color:var(--pptx-primary);cursor:help}.pptx-ng-options-check{width:15px;height:15px;flex-shrink:0;accent-color:var(--pptx-primary)}.pptx-ng-options-select,.pptx-ng-options-text,.pptx-ng-options-number input{max-width:55%;padding:3px 6px;border:1px solid var(--pptx-border);border-radius:4px;background:var(--pptx-background);color:var(--pptx-foreground);font-size:12px}.pptx-ng-options-number{display:inline-flex;align-items:center;gap:6px}.pptx-ng-options-number input{width:72px;text-align:right}.pptx-ng-options-text{width:180px}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95830
+ }
95831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsPaneComponent, decorators: [{
95832
+ type: Component,
95833
+ args: [{ selector: 'pptx-options-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
95834
+ <div class="pptx-ng-options-pane">
95835
+ <p class="pptx-ng-options-headline">{{ tab().descriptionKey | translate }}</p>
95836
+ @for (section of tab().sections; track section.id) {
95837
+ <section class="pptx-ng-options-section">
95838
+ <h3>{{ section.titleKey | translate }}</h3>
95839
+ @if (section.descriptionKey; as descriptionKey) {
95840
+ <p class="pptx-ng-options-note">{{ descriptionKey | translate }}</p>
95841
+ }
95842
+ @for (control of section.controls; track control.group + '.' + control.key) {
95843
+ <div class="pptx-ng-options-row" [class.is-indented]="control.indent">
95844
+ <span class="pptx-ng-options-label">
95845
+ {{ control.labelKey | translate }}
95846
+ @if (control.infoKey; as infoKey) {
95847
+ <span
95848
+ class="pptx-ng-options-info"
95849
+ [title]="infoKey | translate"
95850
+ aria-hidden="true"
95851
+ >&#9432;</span
95852
+ >
95853
+ }
95854
+ </span>
95855
+ @switch (control.kind) {
95856
+ @case ('toggle') {
95857
+ <input
95858
+ type="checkbox"
95859
+ class="pptx-ng-options-check"
95860
+ [checked]="value(control) === true"
95861
+ [attr.aria-label]="control.labelKey | translate"
95862
+ (change)="emitToggle(control, $event)"
95863
+ />
95864
+ }
95865
+ @case ('select') {
95866
+ <select
95867
+ class="pptx-ng-options-select"
95868
+ [value]="value(control)"
95869
+ [attr.aria-label]="control.labelKey | translate"
95870
+ (change)="emitSelect(control, $event)"
95871
+ >
95872
+ @for (choice of selectChoices(control); track choice.value) {
95873
+ <option [value]="choice.value" [selected]="choice.value === value(control)">
95874
+ {{ choice.labelKey | translate }}
95875
+ </option>
95876
+ }
95877
+ </select>
95878
+ }
95879
+ @case ('number') {
95880
+ <span class="pptx-ng-options-number">
95881
+ <input
95882
+ type="number"
95883
+ [min]="numberMin(control)"
95884
+ [max]="numberMax(control)"
95885
+ [value]="value(control)"
95886
+ [attr.aria-label]="control.labelKey | translate"
95887
+ (change)="emitNumber(control, $event)"
95888
+ />
95889
+ @if (numberUnitKey(control); as unitKey) {
95890
+ <span class="pptx-ng-options-note">{{ unitKey | translate }}</span>
95891
+ }
95892
+ </span>
95893
+ }
95894
+ @default {
95895
+ <input
95896
+ type="text"
95897
+ class="pptx-ng-options-text"
95898
+ maxlength="64"
95899
+ [value]="value(control) ?? ''"
95900
+ [attr.aria-label]="control.labelKey | translate"
95901
+ (change)="emitText(control, $event)"
95902
+ />
95903
+ }
95904
+ }
95905
+ </div>
95906
+ }
95907
+ @if (section.special === 'themePicker') {
95908
+ <ng-content select="[themePicker]" />
95909
+ } @else if (section.special === 'clearCache') {
95910
+ <p class="pptx-ng-options-note">
95911
+ {{ 'pptx.options.save.clearCacheDescription' | translate }}
95912
+ </p>
95913
+ <button type="button" class="pptx-ng-options-btn" (click)="clearCache.emit()">
95914
+ {{ 'pptx.options.save.clearCacheNow' | translate }}
95915
+ </button>
95916
+ }
95917
+ </section>
95918
+ }
95919
+ <ng-content />
95920
+ </div>
95921
+ `, styles: [".pptx-ng-options-pane{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-headline{margin:0;font-size:13px;font-weight:600}.pptx-ng-options-section h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:5px 0;font-size:13px}.pptx-ng-options-row.is-indented{padding-left:22px}.pptx-ng-options-info{margin-left:4px;color:var(--pptx-primary);cursor:help}.pptx-ng-options-check{width:15px;height:15px;flex-shrink:0;accent-color:var(--pptx-primary)}.pptx-ng-options-select,.pptx-ng-options-text,.pptx-ng-options-number input{max-width:55%;padding:3px 6px;border:1px solid var(--pptx-border);border-radius:4px;background:var(--pptx-background);color:var(--pptx-foreground);font-size:12px}.pptx-ng-options-number{display:inline-flex;align-items:center;gap:6px}.pptx-ng-options-number input{width:72px;text-align:right}.pptx-ng-options-text{width:180px}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}\n"] }]
95922
+ }], propDecorators: { tab: [{ type: i0.Input, args: [{ isSignal: true, alias: "tab", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], clearCache: [{ type: i0.Output, args: ["clearCache"] }] } });
95923
+
95924
+ /**
95925
+ * options-quick-access-pane.component.ts: Options > Quick Access Toolbar pane
95926
+ * (Angular port of React's `settings/OptionsQuickAccessPane.tsx`).
95927
+ *
95928
+ * PowerPoint's dual-list command chooser over the shared
95929
+ * {@link QUICK_ACCESS_COMMAND_CATALOG}: available commands on the left, the
95930
+ * current toolbar on the right, Add/Remove between them, reorder arrows, and a
95931
+ * Reset back to {@link DEFAULT_QUICK_ACCESS_COMMAND_IDS}.
95932
+ */
95933
+ class OptionsQuickAccessPaneComponent {
95934
+ options = input.required(/* @ts-ignore */
95935
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
95936
+ /** The full replacement command-id list (applied live by the host). */
95937
+ commandsChange = output();
95938
+ selectedAvailable = signal(null, /* @ts-ignore */
95939
+ ...(ngDevMode ? [{ debugName: "selectedAvailable" }] : /* istanbul ignore next */ []));
95940
+ selectedCurrent = signal(null, /* @ts-ignore */
95941
+ ...(ngDevMode ? [{ debugName: "selectedCurrent" }] : /* istanbul ignore next */ []));
95942
+ current = computed(() => this.options().quickAccess.commandIds, /* @ts-ignore */
95943
+ ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
95944
+ available = computed(() => availableQuickAccessCommands(this.current()).map((entry) => entry.id), /* @ts-ignore */
95945
+ ...(ngDevMode ? [{ debugName: "available" }] : /* istanbul ignore next */ []));
95946
+ labelKey(id) {
95947
+ return getQuickAccessCommand(id)?.labelKey ?? id;
95948
+ }
95949
+ add() {
95950
+ const id = this.selectedAvailable();
95951
+ if (id) {
95952
+ this.commandsChange.emit(addQuickAccessCommand(this.current(), id));
95953
+ this.selectedAvailable.set(null);
95954
+ }
95955
+ }
95956
+ remove() {
95957
+ const id = this.selectedCurrent();
95958
+ if (id) {
95959
+ this.commandsChange.emit(removeQuickAccessCommand(this.current(), id));
95960
+ this.selectedCurrent.set(null);
95961
+ }
95962
+ }
95963
+ move(direction) {
95964
+ const id = this.selectedCurrent();
95965
+ if (id) {
95966
+ this.commandsChange.emit(moveQuickAccessCommand(this.current(), id, direction));
95967
+ }
95968
+ }
95969
+ reset() {
95970
+ this.commandsChange.emit([...DEFAULT_QUICK_ACCESS_COMMAND_IDS]);
95971
+ }
95972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsQuickAccessPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsQuickAccessPaneComponent, isStandalone: true, selector: "pptx-options-quick-access-pane", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { commandsChange: "commandsChange" }, ngImport: i0, template: `
95974
+ <div class="pptx-ng-options-qat">
95975
+ <div class="pptx-ng-options-qat-lists">
95976
+ <div class="pptx-ng-options-qat-col">
95977
+ <p>{{ 'pptx.options.quickAccess.chooseCommands' | translate }}</p>
95978
+ <div
95979
+ role="listbox"
95980
+ [attr.aria-label]="'pptx.options.quickAccess.chooseCommands' | translate"
95981
+ >
95982
+ @for (id of available(); track id) {
95983
+ <button
95984
+ type="button"
95985
+ role="option"
95986
+ [attr.aria-selected]="selectedAvailable() === id"
95987
+ [class.is-selected]="selectedAvailable() === id"
95988
+ (click)="selectedAvailable.set(id)"
95989
+ >
95990
+ {{ labelKey(id) | translate }}
95991
+ </button>
95992
+ }
95993
+ </div>
95994
+ </div>
95995
+ <div class="pptx-ng-options-qat-actions">
95996
+ <button
95997
+ type="button"
95998
+ class="pptx-ng-options-btn"
95999
+ [disabled]="!selectedAvailable()"
96000
+ (click)="add()"
96001
+ >
96002
+ {{ 'pptx.options.quickAccess.add' | translate }} &raquo;
96003
+ </button>
96004
+ <button
96005
+ type="button"
96006
+ class="pptx-ng-options-btn"
96007
+ [disabled]="!selectedCurrent()"
96008
+ (click)="remove()"
96009
+ >
96010
+ &laquo; {{ 'pptx.options.quickAccess.remove' | translate }}
96011
+ </button>
96012
+ </div>
96013
+ <div class="pptx-ng-options-qat-col">
96014
+ <p>{{ 'pptx.options.quickAccess.currentCommands' | translate }}</p>
96015
+ <div
96016
+ role="listbox"
96017
+ [attr.aria-label]="'pptx.options.quickAccess.currentCommands' | translate"
96018
+ >
96019
+ @for (id of current(); track id) {
96020
+ <button
96021
+ type="button"
96022
+ role="option"
96023
+ [attr.aria-selected]="selectedCurrent() === id"
96024
+ [class.is-selected]="selectedCurrent() === id"
96025
+ (click)="selectedCurrent.set(id)"
96026
+ >
96027
+ {{ labelKey(id) | translate }}
96028
+ </button>
96029
+ }
96030
+ </div>
96031
+ </div>
96032
+ <div class="pptx-ng-options-qat-actions">
96033
+ <button
96034
+ type="button"
96035
+ class="pptx-ng-options-btn"
96036
+ [disabled]="!selectedCurrent()"
96037
+ [attr.aria-label]="'pptx.options.quickAccess.moveUp' | translate"
96038
+ (click)="move('up')"
96039
+ >
96040
+ &#9650;
96041
+ </button>
96042
+ <button
96043
+ type="button"
96044
+ class="pptx-ng-options-btn"
96045
+ [disabled]="!selectedCurrent()"
96046
+ [attr.aria-label]="'pptx.options.quickAccess.moveDown' | translate"
96047
+ (click)="move('down')"
96048
+ >
96049
+ &#9660;
96050
+ </button>
96051
+ </div>
96052
+ </div>
96053
+ <button type="button" class="pptx-ng-options-btn" (click)="reset()">
96054
+ {{ 'pptx.options.quickAccess.reset' | translate }}
96055
+ </button>
96056
+ </div>
96057
+ `, isInline: true, styles: [".pptx-ng-options-qat{display:flex;flex-direction:column;gap:10px}.pptx-ng-options-qat-lists{display:flex;align-items:stretch;gap:10px}.pptx-ng-options-qat-col{flex:1;min-width:0}.pptx-ng-options-qat-col p{margin:0 0 4px;color:var(--pptx-muted-foreground);font-size:11px;font-weight:600}.pptx-ng-options-qat-col [role=listbox]{height:190px;overflow-y:auto;padding:4px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-qat-col [role=option]{display:block;width:100%;padding:5px 8px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;cursor:pointer}.pptx-ng-options-qat-col [role=option]:hover{background:var(--pptx-accent)}.pptx-ng-options-qat-col [role=option].is-selected{background:color-mix(in srgb,var(--pptx-primary) 15%,transparent);color:var(--pptx-primary)}.pptx-ng-options-qat-actions{display:flex;flex-direction:column;justify-content:center;gap:8px}.pptx-ng-options-btn{padding:5px 10px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;white-space:nowrap;cursor:pointer}.pptx-ng-options-btn:hover:not(:disabled){background:var(--pptx-accent)}.pptx-ng-options-btn:disabled{opacity:.5;cursor:not-allowed}.pptx-ng-options-qat>.pptx-ng-options-btn{align-self:flex-start}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96058
+ }
96059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsQuickAccessPaneComponent, decorators: [{
96060
+ type: Component,
96061
+ args: [{ selector: 'pptx-options-quick-access-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
96062
+ <div class="pptx-ng-options-qat">
96063
+ <div class="pptx-ng-options-qat-lists">
96064
+ <div class="pptx-ng-options-qat-col">
96065
+ <p>{{ 'pptx.options.quickAccess.chooseCommands' | translate }}</p>
96066
+ <div
96067
+ role="listbox"
96068
+ [attr.aria-label]="'pptx.options.quickAccess.chooseCommands' | translate"
96069
+ >
96070
+ @for (id of available(); track id) {
96071
+ <button
96072
+ type="button"
96073
+ role="option"
96074
+ [attr.aria-selected]="selectedAvailable() === id"
96075
+ [class.is-selected]="selectedAvailable() === id"
96076
+ (click)="selectedAvailable.set(id)"
96077
+ >
96078
+ {{ labelKey(id) | translate }}
96079
+ </button>
96080
+ }
96081
+ </div>
96082
+ </div>
96083
+ <div class="pptx-ng-options-qat-actions">
96084
+ <button
96085
+ type="button"
96086
+ class="pptx-ng-options-btn"
96087
+ [disabled]="!selectedAvailable()"
96088
+ (click)="add()"
96089
+ >
96090
+ {{ 'pptx.options.quickAccess.add' | translate }} &raquo;
96091
+ </button>
96092
+ <button
96093
+ type="button"
96094
+ class="pptx-ng-options-btn"
96095
+ [disabled]="!selectedCurrent()"
96096
+ (click)="remove()"
96097
+ >
96098
+ &laquo; {{ 'pptx.options.quickAccess.remove' | translate }}
96099
+ </button>
96100
+ </div>
96101
+ <div class="pptx-ng-options-qat-col">
96102
+ <p>{{ 'pptx.options.quickAccess.currentCommands' | translate }}</p>
96103
+ <div
96104
+ role="listbox"
96105
+ [attr.aria-label]="'pptx.options.quickAccess.currentCommands' | translate"
96106
+ >
96107
+ @for (id of current(); track id) {
96108
+ <button
96109
+ type="button"
96110
+ role="option"
96111
+ [attr.aria-selected]="selectedCurrent() === id"
96112
+ [class.is-selected]="selectedCurrent() === id"
96113
+ (click)="selectedCurrent.set(id)"
96114
+ >
96115
+ {{ labelKey(id) | translate }}
96116
+ </button>
96117
+ }
96118
+ </div>
96119
+ </div>
96120
+ <div class="pptx-ng-options-qat-actions">
96121
+ <button
96122
+ type="button"
96123
+ class="pptx-ng-options-btn"
96124
+ [disabled]="!selectedCurrent()"
96125
+ [attr.aria-label]="'pptx.options.quickAccess.moveUp' | translate"
96126
+ (click)="move('up')"
96127
+ >
96128
+ &#9650;
96129
+ </button>
96130
+ <button
96131
+ type="button"
96132
+ class="pptx-ng-options-btn"
96133
+ [disabled]="!selectedCurrent()"
96134
+ [attr.aria-label]="'pptx.options.quickAccess.moveDown' | translate"
96135
+ (click)="move('down')"
96136
+ >
96137
+ &#9660;
96138
+ </button>
96139
+ </div>
96140
+ </div>
96141
+ <button type="button" class="pptx-ng-options-btn" (click)="reset()">
96142
+ {{ 'pptx.options.quickAccess.reset' | translate }}
96143
+ </button>
96144
+ </div>
96145
+ `, styles: [".pptx-ng-options-qat{display:flex;flex-direction:column;gap:10px}.pptx-ng-options-qat-lists{display:flex;align-items:stretch;gap:10px}.pptx-ng-options-qat-col{flex:1;min-width:0}.pptx-ng-options-qat-col p{margin:0 0 4px;color:var(--pptx-muted-foreground);font-size:11px;font-weight:600}.pptx-ng-options-qat-col [role=listbox]{height:190px;overflow-y:auto;padding:4px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-qat-col [role=option]{display:block;width:100%;padding:5px 8px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;cursor:pointer}.pptx-ng-options-qat-col [role=option]:hover{background:var(--pptx-accent)}.pptx-ng-options-qat-col [role=option].is-selected{background:color-mix(in srgb,var(--pptx-primary) 15%,transparent);color:var(--pptx-primary)}.pptx-ng-options-qat-actions{display:flex;flex-direction:column;justify-content:center;gap:8px}.pptx-ng-options-btn{padding:5px 10px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;white-space:nowrap;cursor:pointer}.pptx-ng-options-btn:hover:not(:disabled){background:var(--pptx-accent)}.pptx-ng-options-btn:disabled{opacity:.5;cursor:not-allowed}.pptx-ng-options-qat>.pptx-ng-options-btn{align-self:flex-start}\n"] }]
96146
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], commandsChange: [{ type: i0.Output, args: ["commandsChange"] }] } });
96147
+
96148
+ /**
96149
+ * options-ribbon-pane.component.ts: Options > Customize Ribbon pane (Angular
96150
+ * port of React's `settings/OptionsRibbonPane.tsx`).
96151
+ *
96152
+ * Renders PowerPoint's "Main Tabs" checkbox tree over the shared
96153
+ * {@link TOOLBAR_TABS} registry (the File tab can never be hidden), a Reset
96154
+ * button that restores the ribbon group, and the keyboard-shortcut reference
96155
+ * list that backs the tab's `shortcutReference` special section.
96156
+ */
96157
+ /** Whether a ribbon tab is ticked in Customize Ribbon (File always is). */
96158
+ function isRibbonTabTicked(options, tabId) {
96159
+ return tabId === 'file' || !options.ribbon.hiddenTabIds.includes(tabId);
96160
+ }
96161
+ class OptionsRibbonPaneComponent {
96162
+ options = input.required(/* @ts-ignore */
96163
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
96164
+ tabHiddenChange = output();
96165
+ resetRibbon = output();
96166
+ tabs = TOOLBAR_TABS;
96167
+ shortcuts = SHORTCUT_REFERENCE_ITEMS;
96168
+ ticked(tabId) {
96169
+ return isRibbonTabTicked(this.options(), tabId);
96170
+ }
96171
+ onTicked(tabId, event) {
96172
+ this.tabHiddenChange.emit({ tabId, hidden: !event.target.checked });
96173
+ }
96174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsRibbonPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
96175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsRibbonPaneComponent, isStandalone: true, selector: "pptx-options-ribbon-pane", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { tabHiddenChange: "tabHiddenChange", resetRibbon: "resetRibbon" }, ngImport: i0, template: `
96176
+ <div class="pptx-ng-options-ribbon">
96177
+ <section>
96178
+ <h3>{{ 'pptx.options.ribbon.tabsTitle' | translate }}</h3>
96179
+ <p class="pptx-ng-options-note">{{ 'pptx.options.ribbon.tabsDescription' | translate }}</p>
96180
+ <div class="pptx-ng-options-ribbon-tabs">
96181
+ @for (tab of tabs; track tab.id) {
96182
+ <label class="pptx-ng-options-ribbon-tab" [class.is-locked]="tab.id === 'file'">
96183
+ <input
96184
+ type="checkbox"
96185
+ [checked]="ticked(tab.id)"
96186
+ [disabled]="tab.id === 'file'"
96187
+ (change)="onTicked(tab.id, $event)"
96188
+ />
96189
+ <span>{{ tab.labelKey | translate }}</span>
96190
+ </label>
96191
+ }
96192
+ </div>
96193
+ <button type="button" class="pptx-ng-options-btn" (click)="resetRibbon.emit()">
96194
+ {{ 'pptx.options.ribbon.reset' | translate }}
96195
+ </button>
96196
+ </section>
96197
+
96198
+ <section>
96199
+ <h3>{{ 'pptx.settings.keyboardShortcuts' | translate }}</h3>
96200
+ @for (item of shortcuts; track item.actionKey; let even = $even) {
96201
+ <div class="pptx-ng-options-shortcut" [class.is-alt]="even">
96202
+ <span>{{ item.actionKey | translate }}</span>
96203
+ <kbd>{{ item.shortcut }}</kbd>
96204
+ </div>
96205
+ }
96206
+ </section>
96207
+ </div>
96208
+ `, isInline: true, styles: [".pptx-ng-options-ribbon{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-ribbon h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-ribbon-tabs{margin-bottom:8px;padding:6px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-ribbon-tab{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;font-size:13px;cursor:pointer}.pptx-ng-options-ribbon-tab:hover{background:var(--pptx-accent)}.pptx-ng-options-ribbon-tab.is-locked{opacity:.6;cursor:not-allowed}.pptx-ng-options-ribbon-tab input{width:15px;height:15px;accent-color:var(--pptx-primary)}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}.pptx-ng-options-shortcut{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 10px;border-radius:4px;font-size:12px}.pptx-ng-options-shortcut.is-alt{background:var(--pptx-muted)}.pptx-ng-options-shortcut kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96209
+ }
96210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsRibbonPaneComponent, decorators: [{
96211
+ type: Component,
96212
+ args: [{ selector: 'pptx-options-ribbon-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
96213
+ <div class="pptx-ng-options-ribbon">
96214
+ <section>
96215
+ <h3>{{ 'pptx.options.ribbon.tabsTitle' | translate }}</h3>
96216
+ <p class="pptx-ng-options-note">{{ 'pptx.options.ribbon.tabsDescription' | translate }}</p>
96217
+ <div class="pptx-ng-options-ribbon-tabs">
96218
+ @for (tab of tabs; track tab.id) {
96219
+ <label class="pptx-ng-options-ribbon-tab" [class.is-locked]="tab.id === 'file'">
96220
+ <input
96221
+ type="checkbox"
96222
+ [checked]="ticked(tab.id)"
96223
+ [disabled]="tab.id === 'file'"
96224
+ (change)="onTicked(tab.id, $event)"
96225
+ />
96226
+ <span>{{ tab.labelKey | translate }}</span>
96227
+ </label>
96228
+ }
96229
+ </div>
96230
+ <button type="button" class="pptx-ng-options-btn" (click)="resetRibbon.emit()">
96231
+ {{ 'pptx.options.ribbon.reset' | translate }}
96232
+ </button>
96233
+ </section>
96234
+
96235
+ <section>
96236
+ <h3>{{ 'pptx.settings.keyboardShortcuts' | translate }}</h3>
96237
+ @for (item of shortcuts; track item.actionKey; let even = $even) {
96238
+ <div class="pptx-ng-options-shortcut" [class.is-alt]="even">
96239
+ <span>{{ item.actionKey | translate }}</span>
96240
+ <kbd>{{ item.shortcut }}</kbd>
96241
+ </div>
96242
+ }
96243
+ </section>
96244
+ </div>
96245
+ `, styles: [".pptx-ng-options-ribbon{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-ribbon h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-ribbon-tabs{margin-bottom:8px;padding:6px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-ribbon-tab{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;font-size:13px;cursor:pointer}.pptx-ng-options-ribbon-tab:hover{background:var(--pptx-accent)}.pptx-ng-options-ribbon-tab.is-locked{opacity:.6;cursor:not-allowed}.pptx-ng-options-ribbon-tab input{width:15px;height:15px;accent-color:var(--pptx-primary)}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}.pptx-ng-options-shortcut{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 10px;border-radius:4px;font-size:12px}.pptx-ng-options-shortcut.is-alt{background:var(--pptx-muted)}.pptx-ng-options-shortcut kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}\n"] }]
96246
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], tabHiddenChange: [{ type: i0.Output, args: ["tabHiddenChange"] }], resetRibbon: [{ type: i0.Output, args: ["resetRibbon"] }] } });
96247
+
94083
96248
  /**
94084
96249
  * settings-appearance-tab.component.ts: File > Options > Appearance tab.
94085
96250
  *
@@ -94193,233 +96358,332 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
94193
96358
  `, styles: [".pptx-ng-lang-row{width:100%;border:0;background:transparent;color:inherit;cursor:pointer}.pptx-ng-lang-row.is-active{color:var(--pptx-primary);font-weight:600}.pptx-ng-lang-en{color:var(--pptx-muted-foreground)}\n"] }]
94194
96359
  }], propDecorators: { locales: [{ type: i0.Input, args: [{ isSignal: true, alias: "locales", required: true }] }], activeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCode", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
94195
96360
 
94196
- function toggleViewerSetting(settings, key) {
94197
- return updateViewerPreference(settings, key, !settings[key]);
96361
+ /**
96362
+ * settings-dialog.component.ts: the File > Options dialog (Angular port of
96363
+ * React's `SettingsDialog.tsx`).
96364
+ *
96365
+ * A PowerPoint Options-style dialog: the ten shared categories from
96366
+ * {@link VIEWER_OPTIONS_TABS} in a left rail, schema-driven panes on the right
96367
+ * ({@link OptionsPaneComponent}), and bespoke panes for Language (locale list),
96368
+ * Customize Ribbon, Quick Access Toolbar, and Add-ins. Changes apply live
96369
+ * through the host's options store; Cancel restores the snapshot taken when
96370
+ * the dialog opened, while OK / Escape / backdrop keep the edits.
96371
+ *
96372
+ * Built as its own overlay + panel (not `pptx-modal-dialog`) because the
96373
+ * two-column rail layout needs the wide footprint the shared modal shell does
96374
+ * not provide, mirroring how `insert-smart-art-dialog` sizes itself.
96375
+ */
96376
+ /** The ten File > Options categories the dialog's rail renders, in order. */
96377
+ const OPTIONS_DIALOG_TABS = VIEWER_OPTIONS_TABS;
96378
+ /** Resolve the active tab definition, falling back to the first category. */
96379
+ function resolveOptionsTab(id) {
96380
+ const fallback = OPTIONS_DIALOG_TABS[0];
96381
+ return OPTIONS_DIALOG_TABS.find((tab) => tab.id === id) ?? fallback;
94198
96382
  }
94199
96383
  class SettingsDialogComponent {
94200
96384
  open = input(false, /* @ts-ignore */
94201
96385
  ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
94202
- settings = input.required(/* @ts-ignore */
94203
- ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
94204
- /** Selected `THEME_CATALOG` (or `availableThemes`) key, for the Appearance tab. */
96386
+ /** Full File > Options snapshot rendered by every pane. */
96387
+ options = input.required(/* @ts-ignore */
96388
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
96389
+ /** Selected theme catalog key, for General > Appearance. */
94205
96390
  themeKey = input('default', /* @ts-ignore */
94206
96391
  ...(ngDevMode ? [{ debugName: "themeKey" }] : /* istanbul ignore next */ []));
94207
- /** Theme choices offered by the Appearance tab. Defaults to the built-in `THEME_CATALOG`. */
94208
96392
  availableThemes = input(THEME_CATALOG, /* @ts-ignore */
94209
96393
  ...(ngDevMode ? [{ debugName: "availableThemes" }] : /* istanbul ignore next */ []));
94210
- /** Active locale code, for the Language tab. */
96394
+ /** Active locale code, for the Language category. */
94211
96395
  localeCode = input('en', /* @ts-ignore */
94212
96396
  ...(ngDevMode ? [{ debugName: "localeCode" }] : /* istanbul ignore next */ []));
94213
- /** Locale choices offered by the Language tab. Defaults to the built-in `LOCALE_CATALOG`. */
94214
96397
  availableLocales = input(LOCALE_CATALOG, /* @ts-ignore */
94215
96398
  ...(ngDevMode ? [{ debugName: "availableLocales" }] : /* istanbul ignore next */ []));
94216
- settingsChange = output();
94217
- /** Fired when the user picks an Appearance tab swatch. */
96399
+ /** Availability flags for the Add-ins pane (unset ids default to active). */
96400
+ addinStatus = input(undefined, /* @ts-ignore */
96401
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
96402
+ optionChange = output();
96403
+ /** Restore a snapshot wholesale (Cancel semantics). */
96404
+ restoreOptions = output();
96405
+ ribbonTabHiddenChange = output();
96406
+ quickAccessCommandsChange = output();
96407
+ /** Reset one tab-group (or everything when `undefined`). */
96408
+ resetOptions = output();
96409
+ clearCache = output();
94218
96410
  themeKeySelect = output();
94219
- /** Fired when the user picks a Language tab entry. */
94220
96411
  localeSelect = output();
94221
96412
  close = output();
94222
- activeTab = signal('general', /* @ts-ignore */
96413
+ tabs = OPTIONS_DIALOG_TABS;
96414
+ activeTabId = signal('general', /* @ts-ignore */
96415
+ ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
96416
+ activeTab = computed(() => resolveOptionsTab(this.activeTabId()), /* @ts-ignore */
94223
96417
  ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
94224
- specs = SETTING_TOGGLES;
94225
- shortcuts = SHORTCUT_REFERENCE_ITEMS;
94226
- toggle(key) {
94227
- this.settingsChange.emit(toggleViewerSetting(this.settings(), key));
96418
+ /** Snapshot taken when the dialog opens, restored by Cancel. */
96419
+ snapshot = null;
96420
+ wasOpen = false;
96421
+ constructor() {
96422
+ effect(() => {
96423
+ const isOpen = this.open();
96424
+ if (isOpen && !this.wasOpen) {
96425
+ this.snapshot = untracked(() => this.options());
96426
+ }
96427
+ this.wasOpen = isOpen;
96428
+ });
96429
+ }
96430
+ /** Cancel: restore the on-open snapshot, then close. */
96431
+ cancel() {
96432
+ if (this.snapshot) {
96433
+ this.restoreOptions.emit(this.snapshot);
96434
+ }
96435
+ this.close.emit();
96436
+ }
96437
+ /** Escape confirms (keeps edits), mirroring React's dialog. */
96438
+ onEscape() {
96439
+ if (this.open()) {
96440
+ this.close.emit();
96441
+ }
94228
96442
  }
94229
96443
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
94230
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SettingsDialogComponent, isStandalone: true, selector: "pptx-settings-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { settingsChange: "settingsChange", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect", close: "close" }, ngImport: i0, template: `
94231
- <pptx-modal-dialog
94232
- [open]="open()"
94233
- [title]="'pptx.settings.title' | translate"
94234
- (close)="close.emit()"
94235
- >
94236
- <div class="pptx-ng-settings">
94237
- <div class="pptx-ng-settings-tabs" role="tablist">
94238
- <button
94239
- type="button"
94240
- role="tab"
94241
- [attr.aria-selected]="activeTab() === 'general'"
94242
- [class.is-active]="activeTab() === 'general'"
94243
- (click)="activeTab.set('general')"
94244
- >
94245
- {{ 'pptx.settings.general' | translate }}
94246
- </button>
94247
- <button
94248
- type="button"
94249
- role="tab"
94250
- [attr.aria-selected]="activeTab() === 'appearance'"
94251
- [class.is-active]="activeTab() === 'appearance'"
94252
- (click)="activeTab.set('appearance')"
94253
- >
94254
- {{ 'pptx.settings.appearance' | translate }}
94255
- </button>
94256
- <button
94257
- type="button"
94258
- role="tab"
94259
- [attr.aria-selected]="activeTab() === 'language'"
94260
- [class.is-active]="activeTab() === 'language'"
94261
- (click)="activeTab.set('language')"
94262
- >
94263
- {{ 'pptx.settings.language' | translate }}
94264
- </button>
96444
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SettingsDialogComponent, isStandalone: true, selector: "pptx-settings-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, addinStatus: { classPropertyName: "addinStatus", publicName: "addinStatus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionChange: "optionChange", restoreOptions: "restoreOptions", ribbonTabHiddenChange: "ribbonTabHiddenChange", quickAccessCommandsChange: "quickAccessCommandsChange", resetOptions: "resetOptions", clearCache: "clearCache", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect", close: "close" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: `
96445
+ @if (open()) {
96446
+ <button
96447
+ type="button"
96448
+ class="pptx-ng-options-backdrop"
96449
+ [attr.aria-label]="'pptx.settings.closeSettings' | translate"
96450
+ (click)="close.emit()"
96451
+ ></button>
96452
+ <div
96453
+ class="pptx-ng-options-modal"
96454
+ role="dialog"
96455
+ aria-modal="true"
96456
+ [attr.aria-label]="'pptx.options.title' | translate"
96457
+ >
96458
+ <div class="pptx-ng-options-header">
96459
+ <h2>{{ 'pptx.options.title' | translate }}</h2>
94265
96460
  <button
94266
96461
  type="button"
94267
- role="tab"
94268
- [attr.aria-selected]="activeTab() === 'shortcuts'"
94269
- [class.is-active]="activeTab() === 'shortcuts'"
94270
- (click)="activeTab.set('shortcuts')"
96462
+ class="pptx-ng-options-x"
96463
+ [attr.aria-label]="'pptx.settings.close' | translate"
96464
+ (click)="close.emit()"
94271
96465
  >
94272
- {{ 'pptx.settings.keyboardShortcuts' | translate }}
96466
+ &#10005;
94273
96467
  </button>
94274
96468
  </div>
94275
96469
 
94276
- @if (activeTab() === 'general') {
94277
- <div class="pptx-ng-settings-list">
94278
- @for (spec of specs; track spec.key) {
94279
- <div class="pptx-ng-settings-row">
94280
- <span>{{ spec.labelKey | translate }}</span>
94281
- <button
94282
- type="button"
94283
- role="switch"
94284
- [attr.aria-checked]="settings()[spec.key]"
94285
- [attr.aria-label]="spec.labelKey | translate"
94286
- [class.is-on]="settings()[spec.key]"
94287
- (click)="toggle(spec.key)"
94288
- >
94289
- <span></span>
94290
- </button>
94291
- </div>
96470
+ <div class="pptx-ng-options-layout">
96471
+ <nav [attr.aria-label]="'pptx.options.title' | translate">
96472
+ @for (tab of tabs; track tab.id) {
96473
+ <button
96474
+ type="button"
96475
+ [attr.aria-current]="activeTabId() === tab.id"
96476
+ [class.is-active]="activeTabId() === tab.id"
96477
+ (click)="activeTabId.set(tab.id)"
96478
+ >
96479
+ {{ tab.labelKey | translate }}
96480
+ </button>
94292
96481
  }
94293
- </div>
94294
- } @else if (activeTab() === 'appearance') {
94295
- <pptx-settings-appearance-tab
94296
- [themes]="availableThemes()"
94297
- [activeKey]="themeKey()"
94298
- (select)="themeKeySelect.emit($event)"
94299
- />
94300
- } @else if (activeTab() === 'language') {
94301
- <pptx-settings-language-tab
94302
- [locales]="availableLocales()"
94303
- [activeCode]="localeCode()"
94304
- (select)="localeSelect.emit($event)"
94305
- />
94306
- } @else {
94307
- <div class="pptx-ng-settings-list">
94308
- @for (item of shortcuts; track item.actionKey; let even = $even) {
94309
- <div class="pptx-ng-shortcut-row" [class.is-alt]="even">
94310
- <span>{{ item.actionKey | translate }}</span>
94311
- <kbd>{{ item.shortcut }}</kbd>
94312
- </div>
96482
+ </nav>
96483
+
96484
+ <div class="pptx-ng-options-content">
96485
+ @switch (activeTab().custom) {
96486
+ @case ('language') {
96487
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96488
+ <h3 class="pptx-ng-options-subhead">
96489
+ {{ 'pptx.options.language.displayLanguage' | translate }}
96490
+ </h3>
96491
+ <p class="pptx-ng-options-note">
96492
+ {{ 'pptx.options.language.displayLanguageDescription' | translate }}
96493
+ </p>
96494
+ <pptx-settings-language-tab
96495
+ [locales]="availableLocales()"
96496
+ [activeCode]="localeCode()"
96497
+ (select)="localeSelect.emit($event)"
96498
+ />
96499
+ }
96500
+ @case ('ribbon') {
96501
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96502
+ <pptx-options-ribbon-pane
96503
+ [options]="options()"
96504
+ (tabHiddenChange)="ribbonTabHiddenChange.emit($event)"
96505
+ (resetRibbon)="resetOptions.emit('ribbon')"
96506
+ />
96507
+ }
96508
+ @case ('addIns') {
96509
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96510
+ <pptx-options-add-ins-pane [addinStatus]="addinStatus()" />
96511
+ }
96512
+ @default {
96513
+ <pptx-options-pane
96514
+ [tab]="activeTab()"
96515
+ [options]="options()"
96516
+ (valueChange)="optionChange.emit($event)"
96517
+ (clearCache)="clearCache.emit()"
96518
+ >
96519
+ <div themePicker>
96520
+ <pptx-settings-appearance-tab
96521
+ [themes]="availableThemes()"
96522
+ [activeKey]="themeKey()"
96523
+ (select)="themeKeySelect.emit($event)"
96524
+ />
96525
+ </div>
96526
+ @if (activeTab().custom === 'quickAccess') {
96527
+ <pptx-options-quick-access-pane
96528
+ [options]="options()"
96529
+ (commandsChange)="quickAccessCommandsChange.emit($event)"
96530
+ />
96531
+ }
96532
+ </pptx-options-pane>
96533
+ }
94313
96534
  }
94314
96535
  </div>
94315
- }
96536
+ </div>
96537
+
96538
+ <div class="pptx-ng-options-footer">
96539
+ <button
96540
+ type="button"
96541
+ class="pptx-ng-options-ghost"
96542
+ (click)="resetOptions.emit(undefined)"
96543
+ >
96544
+ {{ 'pptx.options.resetAll' | translate }}
96545
+ </button>
96546
+ <span class="pptx-ng-options-footer-end">
96547
+ <button type="button" class="pptx-ng-options-ghost" (click)="cancel()">
96548
+ {{ 'pptx.common.cancel' | translate }}
96549
+ </button>
96550
+ <button type="button" class="pptx-ng-options-ok" (click)="close.emit()">
96551
+ {{ 'pptx.common.ok' | translate }}
96552
+ </button>
96553
+ </span>
96554
+ </div>
94316
96555
  </div>
94317
- <button footer type="button" class="pptx-ng-settings-done" (click)="close.emit()">
94318
- {{ 'pptx.settings.done' | translate }}
94319
- </button>
94320
- </pptx-modal-dialog>
94321
- `, isInline: true, styles: [".pptx-ng-settings{min-width:320px}.pptx-ng-settings-tabs{display:flex;flex-wrap:wrap;gap:4px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-settings-tabs button{padding:7px 10px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--pptx-muted-foreground);font-size:12px;cursor:pointer}.pptx-ng-settings-tabs button.is-active{border-bottom-color:var(--pptx-primary);color:var(--pptx-primary)}.pptx-ng-settings-list{max-height:56vh;overflow-y:auto;padding-top:8px}.pptx-ng-settings-row,.pptx-ng-shortcut-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 10px;font-size:13px}.pptx-ng-settings-row button{position:relative;width:36px;height:20px;padding:0;border:0;border-radius:999px;background:color-mix(in srgb,var(--pptx-muted-foreground) 30%,transparent);cursor:pointer}.pptx-ng-settings-row button span{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .12s ease}.pptx-ng-settings-row button.is-on{background:var(--pptx-primary)}.pptx-ng-settings-row button.is-on span{transform:translate(16px)}.pptx-ng-shortcut-row.is-alt{background:var(--pptx-muted)}.pptx-ng-shortcut-row kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}.pptx-ng-settings-done{border:0;border-radius:4px;padding:7px 14px;background:var(--pptx-primary);color:#fff;cursor:pointer}\n"], dependencies: [{ kind: "component", type: ModalDialogComponent, selector: "pptx-modal-dialog", inputs: ["open", "title"], outputs: ["close"] }, { kind: "component", type: SettingsAppearanceTabComponent, selector: "pptx-settings-appearance-tab", inputs: ["themes", "activeKey"], outputs: ["select"] }, { kind: "component", type: SettingsLanguageTabComponent, selector: "pptx-settings-language-tab", inputs: ["locales", "activeCode"], outputs: ["select"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96556
+ }
96557
+ `, isInline: true, styles: [".pptx-ng-options-backdrop{position:fixed;inset:0;z-index:1200;border:0;background:#0009;cursor:default}.pptx-ng-options-modal{position:fixed;top:50%;left:50%;z-index:1201;display:flex;flex-direction:column;width:min(56rem,calc(100vw - 2rem));max-height:85vh;transform:translate(-50%,-50%);border:1px solid var(--pptx-border);border-radius:12px;background:var(--pptx-popover, var(--pptx-background));color:var(--pptx-foreground);box-shadow:0 24px 64px #00000059}.pptx-ng-options-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-options-header h2{margin:0;font-size:14px;font-weight:600}.pptx-ng-options-x{border:0;border-radius:4px;padding:4px 8px;background:transparent;color:var(--pptx-muted-foreground);cursor:pointer}.pptx-ng-options-x:hover{background:var(--pptx-accent)}.pptx-ng-options-layout{display:flex;flex:1;min-height:0}.pptx-ng-options-layout nav{display:flex;flex-direction:column;gap:2px;width:176px;flex-shrink:0;overflow-y:auto;padding:8px;border-right:1px solid var(--pptx-border)}.pptx-ng-options-layout nav button{padding:8px 12px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;white-space:nowrap;cursor:pointer}.pptx-ng-options-layout nav button:hover{background:var(--pptx-accent)}.pptx-ng-options-layout nav button.is-active{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent);color:var(--pptx-primary);font-weight:500}.pptx-ng-options-content{flex:1;min-height:0;min-width:0;overflow-y:auto;padding:16px 20px}.pptx-ng-options-headline{margin:0 0 12px;font-size:13px;font-weight:600}.pptx-ng-options-subhead{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 20px;border-top:1px solid var(--pptx-border)}.pptx-ng-options-footer-end{display:inline-flex;gap:8px}.pptx-ng-options-ghost,.pptx-ng-options-ok{padding:6px 16px;border-radius:4px;font-size:12px;cursor:pointer}.pptx-ng-options-ghost{border:1px solid var(--pptx-border);background:transparent;color:var(--pptx-foreground)}.pptx-ng-options-ghost:hover{background:var(--pptx-accent)}.pptx-ng-options-ok{border:0;background:var(--pptx-primary);color:#fff;font-weight:500}\n"], dependencies: [{ kind: "component", type: OptionsPaneComponent, selector: "pptx-options-pane", inputs: ["tab", "options"], outputs: ["valueChange", "clearCache"] }, { kind: "component", type: OptionsRibbonPaneComponent, selector: "pptx-options-ribbon-pane", inputs: ["options"], outputs: ["tabHiddenChange", "resetRibbon"] }, { kind: "component", type: OptionsQuickAccessPaneComponent, selector: "pptx-options-quick-access-pane", inputs: ["options"], outputs: ["commandsChange"] }, { kind: "component", type: OptionsAddInsPaneComponent, selector: "pptx-options-add-ins-pane", inputs: ["addinStatus"] }, { kind: "component", type: SettingsAppearanceTabComponent, selector: "pptx-settings-appearance-tab", inputs: ["themes", "activeKey"], outputs: ["select"] }, { kind: "component", type: SettingsLanguageTabComponent, selector: "pptx-settings-language-tab", inputs: ["locales", "activeCode"], outputs: ["select"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
94322
96558
  }
94323
96559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SettingsDialogComponent, decorators: [{
94324
96560
  type: Component,
94325
96561
  args: [{ selector: 'pptx-settings-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
94326
- ModalDialogComponent,
94327
96562
  TranslatePipe,
96563
+ OptionsPaneComponent,
96564
+ OptionsRibbonPaneComponent,
96565
+ OptionsQuickAccessPaneComponent,
96566
+ OptionsAddInsPaneComponent,
94328
96567
  SettingsAppearanceTabComponent,
94329
96568
  SettingsLanguageTabComponent,
94330
96569
  ], template: `
94331
- <pptx-modal-dialog
94332
- [open]="open()"
94333
- [title]="'pptx.settings.title' | translate"
94334
- (close)="close.emit()"
94335
- >
94336
- <div class="pptx-ng-settings">
94337
- <div class="pptx-ng-settings-tabs" role="tablist">
94338
- <button
94339
- type="button"
94340
- role="tab"
94341
- [attr.aria-selected]="activeTab() === 'general'"
94342
- [class.is-active]="activeTab() === 'general'"
94343
- (click)="activeTab.set('general')"
94344
- >
94345
- {{ 'pptx.settings.general' | translate }}
94346
- </button>
94347
- <button
94348
- type="button"
94349
- role="tab"
94350
- [attr.aria-selected]="activeTab() === 'appearance'"
94351
- [class.is-active]="activeTab() === 'appearance'"
94352
- (click)="activeTab.set('appearance')"
94353
- >
94354
- {{ 'pptx.settings.appearance' | translate }}
94355
- </button>
94356
- <button
94357
- type="button"
94358
- role="tab"
94359
- [attr.aria-selected]="activeTab() === 'language'"
94360
- [class.is-active]="activeTab() === 'language'"
94361
- (click)="activeTab.set('language')"
94362
- >
94363
- {{ 'pptx.settings.language' | translate }}
94364
- </button>
96570
+ @if (open()) {
96571
+ <button
96572
+ type="button"
96573
+ class="pptx-ng-options-backdrop"
96574
+ [attr.aria-label]="'pptx.settings.closeSettings' | translate"
96575
+ (click)="close.emit()"
96576
+ ></button>
96577
+ <div
96578
+ class="pptx-ng-options-modal"
96579
+ role="dialog"
96580
+ aria-modal="true"
96581
+ [attr.aria-label]="'pptx.options.title' | translate"
96582
+ >
96583
+ <div class="pptx-ng-options-header">
96584
+ <h2>{{ 'pptx.options.title' | translate }}</h2>
94365
96585
  <button
94366
96586
  type="button"
94367
- role="tab"
94368
- [attr.aria-selected]="activeTab() === 'shortcuts'"
94369
- [class.is-active]="activeTab() === 'shortcuts'"
94370
- (click)="activeTab.set('shortcuts')"
96587
+ class="pptx-ng-options-x"
96588
+ [attr.aria-label]="'pptx.settings.close' | translate"
96589
+ (click)="close.emit()"
94371
96590
  >
94372
- {{ 'pptx.settings.keyboardShortcuts' | translate }}
96591
+ &#10005;
94373
96592
  </button>
94374
96593
  </div>
94375
96594
 
94376
- @if (activeTab() === 'general') {
94377
- <div class="pptx-ng-settings-list">
94378
- @for (spec of specs; track spec.key) {
94379
- <div class="pptx-ng-settings-row">
94380
- <span>{{ spec.labelKey | translate }}</span>
94381
- <button
94382
- type="button"
94383
- role="switch"
94384
- [attr.aria-checked]="settings()[spec.key]"
94385
- [attr.aria-label]="spec.labelKey | translate"
94386
- [class.is-on]="settings()[spec.key]"
94387
- (click)="toggle(spec.key)"
94388
- >
94389
- <span></span>
94390
- </button>
94391
- </div>
96595
+ <div class="pptx-ng-options-layout">
96596
+ <nav [attr.aria-label]="'pptx.options.title' | translate">
96597
+ @for (tab of tabs; track tab.id) {
96598
+ <button
96599
+ type="button"
96600
+ [attr.aria-current]="activeTabId() === tab.id"
96601
+ [class.is-active]="activeTabId() === tab.id"
96602
+ (click)="activeTabId.set(tab.id)"
96603
+ >
96604
+ {{ tab.labelKey | translate }}
96605
+ </button>
94392
96606
  }
94393
- </div>
94394
- } @else if (activeTab() === 'appearance') {
94395
- <pptx-settings-appearance-tab
94396
- [themes]="availableThemes()"
94397
- [activeKey]="themeKey()"
94398
- (select)="themeKeySelect.emit($event)"
94399
- />
94400
- } @else if (activeTab() === 'language') {
94401
- <pptx-settings-language-tab
94402
- [locales]="availableLocales()"
94403
- [activeCode]="localeCode()"
94404
- (select)="localeSelect.emit($event)"
94405
- />
94406
- } @else {
94407
- <div class="pptx-ng-settings-list">
94408
- @for (item of shortcuts; track item.actionKey; let even = $even) {
94409
- <div class="pptx-ng-shortcut-row" [class.is-alt]="even">
94410
- <span>{{ item.actionKey | translate }}</span>
94411
- <kbd>{{ item.shortcut }}</kbd>
94412
- </div>
96607
+ </nav>
96608
+
96609
+ <div class="pptx-ng-options-content">
96610
+ @switch (activeTab().custom) {
96611
+ @case ('language') {
96612
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96613
+ <h3 class="pptx-ng-options-subhead">
96614
+ {{ 'pptx.options.language.displayLanguage' | translate }}
96615
+ </h3>
96616
+ <p class="pptx-ng-options-note">
96617
+ {{ 'pptx.options.language.displayLanguageDescription' | translate }}
96618
+ </p>
96619
+ <pptx-settings-language-tab
96620
+ [locales]="availableLocales()"
96621
+ [activeCode]="localeCode()"
96622
+ (select)="localeSelect.emit($event)"
96623
+ />
96624
+ }
96625
+ @case ('ribbon') {
96626
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96627
+ <pptx-options-ribbon-pane
96628
+ [options]="options()"
96629
+ (tabHiddenChange)="ribbonTabHiddenChange.emit($event)"
96630
+ (resetRibbon)="resetOptions.emit('ribbon')"
96631
+ />
96632
+ }
96633
+ @case ('addIns') {
96634
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96635
+ <pptx-options-add-ins-pane [addinStatus]="addinStatus()" />
96636
+ }
96637
+ @default {
96638
+ <pptx-options-pane
96639
+ [tab]="activeTab()"
96640
+ [options]="options()"
96641
+ (valueChange)="optionChange.emit($event)"
96642
+ (clearCache)="clearCache.emit()"
96643
+ >
96644
+ <div themePicker>
96645
+ <pptx-settings-appearance-tab
96646
+ [themes]="availableThemes()"
96647
+ [activeKey]="themeKey()"
96648
+ (select)="themeKeySelect.emit($event)"
96649
+ />
96650
+ </div>
96651
+ @if (activeTab().custom === 'quickAccess') {
96652
+ <pptx-options-quick-access-pane
96653
+ [options]="options()"
96654
+ (commandsChange)="quickAccessCommandsChange.emit($event)"
96655
+ />
96656
+ }
96657
+ </pptx-options-pane>
96658
+ }
94413
96659
  }
94414
96660
  </div>
94415
- }
96661
+ </div>
96662
+
96663
+ <div class="pptx-ng-options-footer">
96664
+ <button
96665
+ type="button"
96666
+ class="pptx-ng-options-ghost"
96667
+ (click)="resetOptions.emit(undefined)"
96668
+ >
96669
+ {{ 'pptx.options.resetAll' | translate }}
96670
+ </button>
96671
+ <span class="pptx-ng-options-footer-end">
96672
+ <button type="button" class="pptx-ng-options-ghost" (click)="cancel()">
96673
+ {{ 'pptx.common.cancel' | translate }}
96674
+ </button>
96675
+ <button type="button" class="pptx-ng-options-ok" (click)="close.emit()">
96676
+ {{ 'pptx.common.ok' | translate }}
96677
+ </button>
96678
+ </span>
96679
+ </div>
94416
96680
  </div>
94417
- <button footer type="button" class="pptx-ng-settings-done" (click)="close.emit()">
94418
- {{ 'pptx.settings.done' | translate }}
94419
- </button>
94420
- </pptx-modal-dialog>
94421
- `, styles: [".pptx-ng-settings{min-width:320px}.pptx-ng-settings-tabs{display:flex;flex-wrap:wrap;gap:4px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-settings-tabs button{padding:7px 10px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--pptx-muted-foreground);font-size:12px;cursor:pointer}.pptx-ng-settings-tabs button.is-active{border-bottom-color:var(--pptx-primary);color:var(--pptx-primary)}.pptx-ng-settings-list{max-height:56vh;overflow-y:auto;padding-top:8px}.pptx-ng-settings-row,.pptx-ng-shortcut-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 10px;font-size:13px}.pptx-ng-settings-row button{position:relative;width:36px;height:20px;padding:0;border:0;border-radius:999px;background:color-mix(in srgb,var(--pptx-muted-foreground) 30%,transparent);cursor:pointer}.pptx-ng-settings-row button span{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .12s ease}.pptx-ng-settings-row button.is-on{background:var(--pptx-primary)}.pptx-ng-settings-row button.is-on span{transform:translate(16px)}.pptx-ng-shortcut-row.is-alt{background:var(--pptx-muted)}.pptx-ng-shortcut-row kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}.pptx-ng-settings-done{border:0;border-radius:4px;padding:7px 14px;background:var(--pptx-primary);color:#fff;cursor:pointer}\n"] }]
94422
- }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }], close: [{ type: i0.Output, args: ["close"] }] } });
96681
+ }
96682
+ `, styles: [".pptx-ng-options-backdrop{position:fixed;inset:0;z-index:1200;border:0;background:#0009;cursor:default}.pptx-ng-options-modal{position:fixed;top:50%;left:50%;z-index:1201;display:flex;flex-direction:column;width:min(56rem,calc(100vw - 2rem));max-height:85vh;transform:translate(-50%,-50%);border:1px solid var(--pptx-border);border-radius:12px;background:var(--pptx-popover, var(--pptx-background));color:var(--pptx-foreground);box-shadow:0 24px 64px #00000059}.pptx-ng-options-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-options-header h2{margin:0;font-size:14px;font-weight:600}.pptx-ng-options-x{border:0;border-radius:4px;padding:4px 8px;background:transparent;color:var(--pptx-muted-foreground);cursor:pointer}.pptx-ng-options-x:hover{background:var(--pptx-accent)}.pptx-ng-options-layout{display:flex;flex:1;min-height:0}.pptx-ng-options-layout nav{display:flex;flex-direction:column;gap:2px;width:176px;flex-shrink:0;overflow-y:auto;padding:8px;border-right:1px solid var(--pptx-border)}.pptx-ng-options-layout nav button{padding:8px 12px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;white-space:nowrap;cursor:pointer}.pptx-ng-options-layout nav button:hover{background:var(--pptx-accent)}.pptx-ng-options-layout nav button.is-active{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent);color:var(--pptx-primary);font-weight:500}.pptx-ng-options-content{flex:1;min-height:0;min-width:0;overflow-y:auto;padding:16px 20px}.pptx-ng-options-headline{margin:0 0 12px;font-size:13px;font-weight:600}.pptx-ng-options-subhead{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 20px;border-top:1px solid var(--pptx-border)}.pptx-ng-options-footer-end{display:inline-flex;gap:8px}.pptx-ng-options-ghost,.pptx-ng-options-ok{padding:6px 16px;border-radius:4px;font-size:12px;cursor:pointer}.pptx-ng-options-ghost{border:1px solid var(--pptx-border);background:transparent;color:var(--pptx-foreground)}.pptx-ng-options-ghost:hover{background:var(--pptx-accent)}.pptx-ng-options-ok{border:0;background:var(--pptx-primary);color:#fff;font-weight:500}\n"] }]
96683
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], addinStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "addinStatus", required: false }] }], optionChange: [{ type: i0.Output, args: ["optionChange"] }], restoreOptions: [{ type: i0.Output, args: ["restoreOptions"] }], ribbonTabHiddenChange: [{ type: i0.Output, args: ["ribbonTabHiddenChange"] }], quickAccessCommandsChange: [{ type: i0.Output, args: ["quickAccessCommandsChange"] }], resetOptions: [{ type: i0.Output, args: ["resetOptions"] }], clearCache: [{ type: i0.Output, args: ["clearCache"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
96684
+ type: HostListener,
96685
+ args: ['document:keydown.escape']
96686
+ }] } });
94423
96687
 
94424
96688
  /** Compatibility barrel for the shared keyboard shortcut reference. */
94425
96689
 
@@ -94905,9 +97169,6 @@ class ViewerExtraDialogsComponent {
94905
97169
  /** Custom shows offered in the set-up-slide-show "show slides" fieldset. */
94906
97170
  customShows = input([], /* @ts-ignore */
94907
97171
  ...(ngDevMode ? [{ debugName: "customShows" }] : /* istanbul ignore next */ []));
94908
- /** Live viewer preferences surfaced by the settings dialog. */
94909
- settings = input.required(/* @ts-ignore */
94910
- ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
94911
97172
  // Settings dialog Appearance/Language tab state; see PowerPointViewerComponent.
94912
97173
  themeKey = input('default', /* @ts-ignore */
94913
97174
  ...(ngDevMode ? [{ debugName: "themeKey" }] : /* istanbul ignore next */ []));
@@ -94919,12 +97180,11 @@ class ViewerExtraDialogsComponent {
94919
97180
  ...(ngDevMode ? [{ debugName: "availableLocales" }] : /* istanbul ignore next */ []));
94920
97181
  /** Fired with a restored `.pptx` version's bytes; the host swaps the deck. */
94921
97182
  restoreContent = output();
94922
- /** Fired whenever a settings toggle changes. */
94923
- settingsChange = output();
94924
97183
  // Fired when the user picks a Settings dialog Appearance/Language selection.
94925
97184
  themeKeySelect = output();
94926
97185
  localeSelect = output();
94927
97186
  svc = inject(ViewerDialogsService);
97187
+ viewerOpts = inject(ViewerOptionsService);
94928
97188
  compare = inject(ViewerCompareService);
94929
97189
  editor = inject(EditorStateService);
94930
97190
  loader = inject(LoadContentService);
@@ -94969,6 +97229,11 @@ class ViewerExtraDialogsComponent {
94969
97229
  if (strokeCount === 0) {
94970
97230
  return;
94971
97231
  }
97232
+ // Options > Advanced > "Prompt to keep ink annotations": when off, the
97233
+ // ink is discarded without asking (PowerPoint parity).
97234
+ if (!this.viewerOpts.options().advanced.slideShowPromptKeepInkAnnotations) {
97235
+ return;
97236
+ }
94972
97237
  this.pendingAnnotations.set(map);
94973
97238
  this.svc.keepAnnotationCount.set(strokeCount);
94974
97239
  this.svc.keepSlideCount.set(map.size);
@@ -94985,6 +97250,10 @@ class ViewerExtraDialogsComponent {
94985
97250
  this.pendingAnnotations.set(null);
94986
97251
  this.svc.showKeepAnnotations.set(false);
94987
97252
  }
97253
+ /** Options > Save > "Delete cached files": purge autosave recovery snapshots. */
97254
+ onClearOptionsCache() {
97255
+ void this.viewerOpts.clearCache();
97256
+ }
94988
97257
  /** Drop the pending presentation ink. */
94989
97258
  onDiscardAnnotations() {
94990
97259
  this.pendingAnnotations.set(null);
@@ -95021,7 +97290,7 @@ class ViewerExtraDialogsComponent {
95021
97290
  this.svc.showPassword.set(false);
95022
97291
  }
95023
97292
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerExtraDialogsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95024
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: ViewerExtraDialogsComponent, isStandalone: true, selector: "pptx-viewer-extra-dialogs", inputs: { activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElementId: { classPropertyName: "selectedElementId", publicName: "selectedElementId", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, customShows: { classPropertyName: "customShows", publicName: "customShows", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restoreContent: "restoreContent", settingsChange: "settingsChange", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
97293
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: ViewerExtraDialogsComponent, isStandalone: true, selector: "pptx-viewer-extra-dialogs", inputs: { activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElementId: { classPropertyName: "selectedElementId", publicName: "selectedElementId", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, customShows: { classPropertyName: "customShows", publicName: "customShows", isSignal: true, isRequired: false, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restoreContent: "restoreContent", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
95025
97294
  <pptx-equation-editor-dialog
95026
97295
  [open]="svc.showEquation()"
95027
97296
  [existingOmml]="svc.editingEquationOmml()"
@@ -95082,12 +97351,17 @@ class ViewerExtraDialogsComponent {
95082
97351
 
95083
97352
  <pptx-settings-dialog
95084
97353
  [open]="svc.showSettings()"
95085
- [settings]="settings()"
97354
+ [options]="viewerOpts.options()"
95086
97355
  [themeKey]="themeKey()"
95087
97356
  [availableThemes]="availableThemes()"
95088
97357
  [localeCode]="localeCode()"
95089
97358
  [availableLocales]="availableLocales()"
95090
- (settingsChange)="settingsChange.emit($event)"
97359
+ (optionChange)="viewerOpts.setValue($event.group, $event.key, $event.value)"
97360
+ (restoreOptions)="viewerOpts.restore($event)"
97361
+ (ribbonTabHiddenChange)="viewerOpts.setRibbonTabHidden($event.tabId, $event.hidden)"
97362
+ (quickAccessCommandsChange)="viewerOpts.setQuickAccessCommands($event)"
97363
+ (resetOptions)="viewerOpts.reset($event)"
97364
+ (clearCache)="onClearOptionsCache()"
95091
97365
  (themeKeySelect)="themeKeySelect.emit($event)"
95092
97366
  (localeSelect)="localeSelect.emit($event)"
95093
97367
  (close)="svc.showSettings.set(false)"
@@ -95114,7 +97388,7 @@ class ViewerExtraDialogsComponent {
95114
97388
  (confirm)="svc.showSignatureStripped.set(false)"
95115
97389
  (cancel)="svc.showSignatureStripped.set(false)"
95116
97390
  />
95117
- `, isInline: true, dependencies: [{ kind: "component", type: EquationEditorDialogComponent, selector: "pptx-equation-editor-dialog", inputs: ["open", "existingOmml"], outputs: ["insert", "close"] }, { kind: "component", type: SetUpSlideShowDialogComponent, selector: "pptx-set-up-slide-show-dialog", inputs: ["open", "properties", "customShows", "slideCount"], outputs: ["save", "close"] }, { kind: "component", type: PasswordProtectionDialogComponent, selector: "pptx-password-protection-dialog", inputs: ["open", "isCurrentlyProtected"], outputs: ["setPassword", "removePassword", "close"] }, { kind: "component", type: EncryptedFileDialogComponent, selector: "pptx-encrypted-file-dialog", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: ComparePanelComponent, selector: "pptx-compare-panel", inputs: ["open", "compareResult", "canvasSize", "mediaDataUrls"], outputs: ["close", "acceptSlide", "rejectSlide", "acceptAll"] }, { kind: "component", type: FontEmbeddingPanelComponent, selector: "pptx-font-embedding-panel", inputs: ["open", "embedFontsEnabled", "usedFontFamilies", "embeddedFonts"], outputs: ["close", "toggleEmbedFonts"] }, { kind: "component", type: VersionHistoryPanelComponent, selector: "pptx-version-history-panel", inputs: ["open", "filePath"], outputs: ["close", "restore"] }, { kind: "component", type: ShortcutPanelComponent, selector: "pptx-shortcut-panel", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: SettingsDialogComponent, selector: "pptx-settings-dialog", inputs: ["open", "settings", "themeKey", "availableThemes", "localeCode", "availableLocales"], outputs: ["settingsChange", "themeKeySelect", "localeSelect", "close"] }, { kind: "component", type: KeepAnnotationsDialogComponent, selector: "pptx-keep-annotations-dialog", inputs: ["open", "annotationCount", "slideCount"], outputs: ["keep", "discard"] }, { kind: "component", type: SignatureStrippedDialogComponent, selector: "pptx-signature-stripped-dialog", inputs: ["open", "signatureCount"], outputs: ["confirm", "cancel"] }, { kind: "component", type: HeaderFooterDialogComponent, selector: "pptx-header-footer-dialog", inputs: ["open", "value"], outputs: ["save", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
97391
+ `, isInline: true, dependencies: [{ kind: "component", type: EquationEditorDialogComponent, selector: "pptx-equation-editor-dialog", inputs: ["open", "existingOmml"], outputs: ["insert", "close"] }, { kind: "component", type: SetUpSlideShowDialogComponent, selector: "pptx-set-up-slide-show-dialog", inputs: ["open", "properties", "customShows", "slideCount"], outputs: ["save", "close"] }, { kind: "component", type: PasswordProtectionDialogComponent, selector: "pptx-password-protection-dialog", inputs: ["open", "isCurrentlyProtected"], outputs: ["setPassword", "removePassword", "close"] }, { kind: "component", type: EncryptedFileDialogComponent, selector: "pptx-encrypted-file-dialog", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: ComparePanelComponent, selector: "pptx-compare-panel", inputs: ["open", "compareResult", "canvasSize", "mediaDataUrls"], outputs: ["close", "acceptSlide", "rejectSlide", "acceptAll"] }, { kind: "component", type: FontEmbeddingPanelComponent, selector: "pptx-font-embedding-panel", inputs: ["open", "embedFontsEnabled", "usedFontFamilies", "embeddedFonts"], outputs: ["close", "toggleEmbedFonts"] }, { kind: "component", type: VersionHistoryPanelComponent, selector: "pptx-version-history-panel", inputs: ["open", "filePath"], outputs: ["close", "restore"] }, { kind: "component", type: ShortcutPanelComponent, selector: "pptx-shortcut-panel", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: SettingsDialogComponent, selector: "pptx-settings-dialog", inputs: ["open", "options", "themeKey", "availableThemes", "localeCode", "availableLocales", "addinStatus"], outputs: ["optionChange", "restoreOptions", "ribbonTabHiddenChange", "quickAccessCommandsChange", "resetOptions", "clearCache", "themeKeySelect", "localeSelect", "close"] }, { kind: "component", type: KeepAnnotationsDialogComponent, selector: "pptx-keep-annotations-dialog", inputs: ["open", "annotationCount", "slideCount"], outputs: ["keep", "discard"] }, { kind: "component", type: SignatureStrippedDialogComponent, selector: "pptx-signature-stripped-dialog", inputs: ["open", "signatureCount"], outputs: ["confirm", "cancel"] }, { kind: "component", type: HeaderFooterDialogComponent, selector: "pptx-header-footer-dialog", inputs: ["open", "value"], outputs: ["save", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95118
97392
  }
95119
97393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerExtraDialogsComponent, decorators: [{
95120
97394
  type: Component,
@@ -95198,12 +97472,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
95198
97472
 
95199
97473
  <pptx-settings-dialog
95200
97474
  [open]="svc.showSettings()"
95201
- [settings]="settings()"
97475
+ [options]="viewerOpts.options()"
95202
97476
  [themeKey]="themeKey()"
95203
97477
  [availableThemes]="availableThemes()"
95204
97478
  [localeCode]="localeCode()"
95205
97479
  [availableLocales]="availableLocales()"
95206
- (settingsChange)="settingsChange.emit($event)"
97480
+ (optionChange)="viewerOpts.setValue($event.group, $event.key, $event.value)"
97481
+ (restoreOptions)="viewerOpts.restore($event)"
97482
+ (ribbonTabHiddenChange)="viewerOpts.setRibbonTabHidden($event.tabId, $event.hidden)"
97483
+ (quickAccessCommandsChange)="viewerOpts.setQuickAccessCommands($event)"
97484
+ (resetOptions)="viewerOpts.reset($event)"
97485
+ (clearCache)="onClearOptionsCache()"
95207
97486
  (themeKeySelect)="themeKeySelect.emit($event)"
95208
97487
  (localeSelect)="localeSelect.emit($event)"
95209
97488
  (close)="svc.showSettings.set(false)"
@@ -95232,7 +97511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
95232
97511
  />
95233
97512
  `,
95234
97513
  }]
95235
- }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
97514
+ }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
95236
97515
 
95237
97516
  /**
95238
97517
  * PowerPointViewerComponent: Angular port of the React `PowerPointViewer.tsx`
@@ -95256,9 +97535,8 @@ class PowerPointViewerComponent {
95256
97535
  ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
95257
97536
  /** Licensed fonts supplied by the host application. No fonts are bundled. */
95258
97537
  fontsInput = input([], { ...(ngDevMode ? { debugName: "fontsInput" } : /* istanbul ignore next */ {}), alias: 'fonts' });
95259
- /** Whether editing actions are enabled. (Editor chrome not yet ported.) */
95260
- canEdit = input(false, /* @ts-ignore */
95261
- ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
97538
+ /** Whether editing actions are enabled (host input; see {@link canEdit}). */
97539
+ canEditInput = input(false, { ...(ngDevMode ? { debugName: "canEditInput" } : /* istanbul ignore next */ {}), alias: 'canEdit' });
95262
97540
  /** Optional class applied to the root element. */
95263
97541
  class = input('', /* @ts-ignore */
95264
97542
  ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
@@ -95396,6 +97674,7 @@ class PowerPointViewerComponent {
95396
97674
  presenterWindow = inject(PresenterWindowService);
95397
97675
  destroyRef = inject(DestroyRef);
95398
97676
  dialogs = inject(ViewerDialogsService);
97677
+ viewerOpts = inject(ViewerOptionsService);
95399
97678
  compareSvc = inject(ViewerCompareService);
95400
97679
  xport = inject(ViewerExportService);
95401
97680
  findReplace = inject(ViewerFindReplaceService);
@@ -95427,6 +97706,13 @@ class PowerPointViewerComponent {
95427
97706
  /** The `<main>` host; used to locate the live `.pptx-ng-canvas-stage`. */
95428
97707
  mainEl = viewChild('mainEl', /* @ts-ignore */
95429
97708
  ...(ngDevMode ? [{ debugName: "mainEl" }] : /* istanbul ignore next */ []));
97709
+ /**
97710
+ * Effective edit permission: the host's `canEdit` input gated by Trust
97711
+ * Center > "Open presentations in Protected View", which forces the deck
97712
+ * read-only while enabled (File > Options wiring, mirrors PowerPoint).
97713
+ */
97714
+ canEdit = computed(() => this.canEditInput() && !this.viewerOpts.options().trust.openInProtectedView, /* @ts-ignore */
97715
+ ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
95430
97716
  activeSlideIndex = signal(0, /* @ts-ignore */
95431
97717
  ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
95432
97718
  /** Slides to display: the editable deck when `canEdit`, else the loaded deck. */
@@ -95577,7 +97863,10 @@ class PowerPointViewerComponent {
95577
97863
  /** User override that suppresses viewer animations and transitions. */
95578
97864
  reducedMotion = signal(false, /* @ts-ignore */
95579
97865
  ...(ngDevMode ? [{ debugName: "reducedMotion" }] : /* istanbul ignore next */ []));
95580
- /** Snapshot consumed by the settings dialog. */
97866
+ /**
97867
+ * The six legacy preference toggles as a snapshot, kept in a guarded
97868
+ * two-way sync with the File > Options store (see the constructor).
97869
+ */
95581
97870
  viewerSettings = computed(() => ({
95582
97871
  autoSave: this.autosaveEnabled(),
95583
97872
  spellCheck: this.spellCheck(),
@@ -95587,6 +97876,17 @@ class PowerPointViewerComponent {
95587
97876
  reducedMotion: this.reducedMotion(),
95588
97877
  }), /* @ts-ignore */
95589
97878
  ...(ngDevMode ? [{ debugName: "viewerSettings" }] : /* istanbul ignore next */ []));
97879
+ /**
97880
+ * Root class list: the host `class` input, the reduced-motion override, and
97881
+ * the option-driven display classes (`resolveOptionRootClasses`, so e.g.
97882
+ * hardware-acceleration and compatibility-display choices are styleable).
97883
+ */
97884
+ rootClasses = computed(() => [
97885
+ this.class(),
97886
+ this.reducedMotion() ? 'pptx-ng-reduced-motion' : '',
97887
+ ...this.viewerOpts.rootClasses(),
97888
+ ], /* @ts-ignore */
97889
+ ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
95590
97890
  /** Whether the Insert SmartArt gallery dialog is open. */
95591
97891
  showSmartArtInsert = signal(false, /* @ts-ignore */
95592
97892
  ...(ngDevMode ? [{ debugName: "showSmartArtInsert" }] : /* istanbul ignore next */ []));
@@ -95621,6 +97921,42 @@ class PowerPointViewerComponent {
95621
97921
  void this.translateService.use(initialLocale);
95622
97922
  }
95623
97923
  });
97924
+ // ── File > Options store ──────────────────────────────────────────
97925
+ // The full PowerPoint Options model lives in ViewerOptionsService
97926
+ // (persisted to localStorage by the shared store). The six legacy
97927
+ // ViewerSettings toggles stay the source of behavior; the two effects
97928
+ // below keep them and the store in sync BOTH ways without echoing:
97929
+ // each side only writes when the mapped values actually differ, and
97930
+ // signal writes are synchronous, so a store change lands on the legacy
97931
+ // signals before the reverse effect re-compares (and vice versa).
97932
+ effect(() => {
97933
+ // Options -> scattered legacy state (dialog edits, persisted values).
97934
+ const mapped = viewerOptionsToPreferences(this.viewerOpts.options());
97935
+ untracked(() => {
97936
+ const current = this.viewerSettings();
97937
+ for (const key of Object.keys(mapped)) {
97938
+ if (mapped[key] !== current[key]) {
97939
+ this.applyPreferenceSnapshot({ ...current, ...mapped });
97940
+ break;
97941
+ }
97942
+ }
97943
+ });
97944
+ });
97945
+ effect(() => {
97946
+ // Legacy state -> options (ribbon View toggles, title-bar autosave).
97947
+ const settings = this.viewerSettings();
97948
+ const current = this.viewerOpts.store.getOptions();
97949
+ const mapped = viewerOptionsToPreferences(current);
97950
+ let next = current;
97951
+ for (const key of Object.keys(mapped)) {
97952
+ if (mapped[key] !== settings[key]) {
97953
+ next = applyPreferenceToOptions(next, key, settings[key]);
97954
+ }
97955
+ }
97956
+ if (next !== current) {
97957
+ this.viewerOpts.store.setOptions(next);
97958
+ }
97959
+ });
95624
97960
  // Surface the `smartArt3D` opt-in to the element dispatcher via the
95625
97961
  // viewer-scoped SmartArt3DService.
95626
97962
  effect(() => {
@@ -95648,6 +97984,15 @@ class PowerPointViewerComponent {
95648
97984
  untracked(() => {
95649
97985
  this.editor.setSlides(slides, this.loader.sections());
95650
97986
  this.activeSlideIndex.set(0);
97987
+ // A load that lands mid-session must not clobber remotely synced
97988
+ // slides: when the shared doc already holds the room's content, a
97989
+ // late joiner's bootstrap deck (parsed slower than the doc sync)
97990
+ // would silently overwrite it here and, with the doc unchanged,
97991
+ // never see it re-applied. Re-adopt the doc's slides synchronously
97992
+ // so the broadcast effect below (which only runs after this effect
97993
+ // completes) sees the adopted deck, never the placeholder, and its
97994
+ // write dedupes against the adopted baseline.
97995
+ this.collab.adoptDocSlidesAfterLoad();
95651
97996
  });
95652
97997
  });
95653
97998
  // Selecting an element re-opens the inspector if a prior swipe had hidden
@@ -95913,6 +98258,8 @@ class PowerPointViewerComponent {
95913
98258
  filePath: () => this.filePath(),
95914
98259
  isDirty: () => this.editor.dirty(),
95915
98260
  serialize: () => this.serializeForAutosave(),
98261
+ // Options > Save > "Save AutoRecover information every N minutes".
98262
+ intervalSeconds: () => this.viewerOpts.autosaveIntervalSeconds(),
95916
98263
  });
95917
98264
  }
95918
98265
  /**
@@ -96362,8 +98709,8 @@ class PowerPointViewerComponent {
96362
98709
  onRestoreVersion(bytes) {
96363
98710
  this.fileIO.contentOverride.set(bytes);
96364
98711
  }
96365
- /** Apply Settings dialog changes to the live editor state. */
96366
- onSettingsChange(settings) {
98712
+ /** Apply one legacy preference snapshot onto the scattered live signals. */
98713
+ applyPreferenceSnapshot(settings) {
96367
98714
  this.autosaveEnabled.set(settings.autoSave);
96368
98715
  this.spellCheck.set(settings.spellCheck);
96369
98716
  this.showGrid.set(settings.showGrid);
@@ -96371,6 +98718,41 @@ class PowerPointViewerComponent {
96371
98718
  this.snapToGrid.set(settings.snapToGrid);
96372
98719
  this.reducedMotion.set(settings.reducedMotion);
96373
98720
  }
98721
+ /** Dispatch a Quick Access Toolbar command id to its existing handler. */
98722
+ onQuickAccessCommand(id) {
98723
+ switch (id) {
98724
+ case 'save':
98725
+ void this.fileIO.saveAsPptx();
98726
+ break;
98727
+ case 'undo':
98728
+ this.editor.undo();
98729
+ break;
98730
+ case 'redo':
98731
+ this.editor.redo();
98732
+ break;
98733
+ case 'presentFromStart':
98734
+ this.presentationMode.presentFromBeginning();
98735
+ break;
98736
+ case 'print':
98737
+ this.print.openDialog();
98738
+ break;
98739
+ case 'exportPdf':
98740
+ void this.xport.exportPdf();
98741
+ break;
98742
+ case 'newSlide':
98743
+ this.editor.addSlide(this.activeSlideIndex());
98744
+ break;
98745
+ case 'spellCheck':
98746
+ this.spellCheck.update((enabled) => !enabled);
98747
+ break;
98748
+ case 'zoomIn':
98749
+ this.zoomSvc.zoomIn();
98750
+ break;
98751
+ case 'zoomOut':
98752
+ this.zoomSvc.zoomOut();
98753
+ break;
98754
+ }
98755
+ }
96374
98756
  /**
96375
98757
  * Mobile "Format" slot: surface the inspector for the current selection.
96376
98758
  * On mobile the format pane starts closed (React parity: the canvas owns
@@ -96434,10 +98816,10 @@ class PowerPointViewerComponent {
96434
98816
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
96435
98817
  }
96436
98818
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
96437
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
98819
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
96438
98820
  <div
96439
98821
  class="pptx-ng-viewer"
96440
- [ngClass]="[class(), reducedMotion() ? 'pptx-ng-reduced-motion' : '']"
98822
+ [ngClass]="rootClasses()"
96441
98823
  [ngStyle]="rootStyle()"
96442
98824
  [attr.aria-busy]="loader.loading()"
96443
98825
  >
@@ -96469,10 +98851,12 @@ class PowerPointViewerComponent {
96469
98851
  [redoLabel]="editor.redoLabel()"
96470
98852
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
96471
98853
  [hiddenActions]="hiddenActions()"
98854
+ [quickAccess]="viewerOpts.options().quickAccess"
96472
98855
  (toggleAutosave)="autosaveEnabled.update(v => !v)"
96473
98856
  (save)="fileIO.saveAsPptx()"
96474
98857
  (undo)="editor.undo()"
96475
98858
  (redo)="editor.redo()"
98859
+ (quickCommand)="onQuickAccessCommand($event)"
96476
98860
  (toggleFindReplace)="toggleFindReplace()"
96477
98861
  (commandSearch)="handleCommandSearch($event)"
96478
98862
  />
@@ -96942,13 +99326,11 @@ class PowerPointViewerComponent {
96942
99326
  [selectedElementId]="selectedElement()?.id ?? null"
96943
99327
  [filePath]="filePath()"
96944
99328
  [customShows]="customShowsCtl.pptxCustomShows()"
96945
- [settings]="viewerSettings()"
96946
99329
  [themeKey]="themeKey()"
96947
99330
  [availableThemes]="resolvedThemes()"
96948
99331
  [localeCode]="localeCode()"
96949
99332
  [availableLocales]="resolvedLocales()"
96950
99333
  (restoreContent)="onRestoreVersion($event)"
96951
- (settingsChange)="onSettingsChange($event)"
96952
99334
  (themeKeySelect)="selectThemeKey($event)"
96953
99335
  (localeSelect)="selectLocale($event)"
96954
99336
  />
@@ -97112,7 +99494,7 @@ class PowerPointViewerComponent {
97112
99494
  />
97113
99495
  }
97114
99496
  </div>
97115
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex"], outputs: ["closed"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "hiddenActions"], outputs: ["toggleMenu", "undo", "redo", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions"], outputs: ["toggleAutosave", "save", "undo", "redo", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "settings", "themeKey", "availableThemes", "localeCode", "availableLocales"], outputs: ["restoreContent", "settingsChange", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
99497
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex"], outputs: ["closed"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "hiddenActions"], outputs: ["toggleMenu", "undo", "redo", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
97116
99498
  }
97117
99499
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PowerPointViewerComponent, decorators: [{
97118
99500
  type: Component,
@@ -97168,7 +99550,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97168
99550
  template: `
97169
99551
  <div
97170
99552
  class="pptx-ng-viewer"
97171
- [ngClass]="[class(), reducedMotion() ? 'pptx-ng-reduced-motion' : '']"
99553
+ [ngClass]="rootClasses()"
97172
99554
  [ngStyle]="rootStyle()"
97173
99555
  [attr.aria-busy]="loader.loading()"
97174
99556
  >
@@ -97200,10 +99582,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97200
99582
  [redoLabel]="editor.redoLabel()"
97201
99583
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
97202
99584
  [hiddenActions]="hiddenActions()"
99585
+ [quickAccess]="viewerOpts.options().quickAccess"
97203
99586
  (toggleAutosave)="autosaveEnabled.update(v => !v)"
97204
99587
  (save)="fileIO.saveAsPptx()"
97205
99588
  (undo)="editor.undo()"
97206
99589
  (redo)="editor.redo()"
99590
+ (quickCommand)="onQuickAccessCommand($event)"
97207
99591
  (toggleFindReplace)="toggleFindReplace()"
97208
99592
  (commandSearch)="handleCommandSearch($event)"
97209
99593
  />
@@ -97673,13 +100057,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97673
100057
  [selectedElementId]="selectedElement()?.id ?? null"
97674
100058
  [filePath]="filePath()"
97675
100059
  [customShows]="customShowsCtl.pptxCustomShows()"
97676
- [settings]="viewerSettings()"
97677
100060
  [themeKey]="themeKey()"
97678
100061
  [availableThemes]="resolvedThemes()"
97679
100062
  [localeCode]="localeCode()"
97680
100063
  [availableLocales]="resolvedLocales()"
97681
100064
  (restoreContent)="onRestoreVersion($event)"
97682
- (settingsChange)="onSettingsChange($event)"
97683
100065
  (themeKeySelect)="selectThemeKey($event)"
97684
100066
  (localeSelect)="selectLocale($event)"
97685
100067
  />
@@ -97845,7 +100227,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97845
100227
  </div>
97846
100228
  `,
97847
100229
  }]
97848
- }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
100230
+ }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEditInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
97849
100231
  type: HostListener,
97850
100232
  args: ['document:keydown', ['$event']]
97851
100233
  }] } });