@dereekb/dbx-web 13.11.18 → 13.12.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.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, input, inject, effect, Directive, NgModule, ChangeDetectionStrategy, Component, output, computed, HostListener, forwardRef, InjectionToken, viewChild, ElementRef, makeEnvironmentProviders, ApplicationRef, Injector, EnvironmentInjector, createComponent, DestroyRef, signal, TemplateRef, model, SecurityContext, ViewContainerRef, booleanAttribute, Renderer2 } from '@angular/core';
3
- import { asPromise, DASH_CHARACTER_PREFIX_INSTANCE, cssTokenVar, isDefinedAndNotFalse, useIterableOrValue, spaceSeparatedCssClasses, cssClassesSet, objectHasNoKeys, getValueFromGetter, firstValue, filterUndefinedValues, separateValues, splitFront, asDecisionFunction, SLASH_PATH_FILE_TYPE_SEPARATOR, filterMaybeArrayValues, mapIterable, toReadableError, isDefaultReadableError, MS_IN_SECOND, mergeObjects, build, ServerErrorResponse, UnauthorizedServerErrorResponse, makeTimer, MS_IN_MINUTE, toggleTimerRunning, unixDateTimeSecondsNumberForNow, ModelRelationUtility, encodeModelKeyTypePair, safeCompareEquality, addMilliseconds, isPast, asArray, slashPathDetails, mimeTypeForFileExtension, slashPathDirectoryTree, isMaybeNot, isNotFalse, modifier, combineMaps, addModifiers, removeModifiers, applyBestFit, findNext, maybeModifierMapToFunction, makeValuesGroupMap, compareWithMappedValuesFunction, invertMaybeBoolean, splitCommaSeparatedStringToSet, ZIP_FILE_MIME_TYPE, cachedGetter, sortByNumberFunction, PDF_MIME_TYPE, PNG_MIME_TYPE, JPEG_MIME_TYPE, JPEG_MIME_TYPES, sequentialIncrementingNumberStringModelIdFactory, PDF_HEADER, PDF_EOF_MARKER, PDF_ENCRYPT_MARKER } from '@dereekb/util';
3
+ import { asPromise, DASH_CHARACTER_PREFIX_INSTANCE, cssTokenVar, isDefinedAndNotFalse, useIterableOrValue, spaceSeparatedCssClasses, cssClassesSet, objectHasNoKeys, getValueFromGetter, firstValue, filterUndefinedValues, separateValues, splitFront, asDecisionFunction, SLASH_PATH_FILE_TYPE_SEPARATOR, filterMaybeArrayValues, mapIterable, toReadableError, isDefaultReadableError, MS_IN_SECOND, mergeObjects, build, ServerErrorResponse, UnauthorizedServerErrorResponse, makeTimer, MS_IN_MINUTE, toggleTimerRunning, unixDateTimeSecondsNumberForNow, ModelRelationUtility, encodeModelKeyTypePair, safeCompareEquality, addMilliseconds, isPast, asArray, slashPathDetails, mimeTypeForFileExtension, slashPathDirectoryTree, isMaybeNot, isNotFalse, modifier, combineMaps, addModifiers, removeModifiers, applyBestFit, findNext, maybeModifierMapToFunction, makeValuesGroupMap, compareWithMappedValuesFunction, invertMaybeBoolean, splitCommaSeparatedStringToSet, ZIP_FILE_MIME_TYPE, cachedGetter, sortByNumberFunction, JPEG_MIME_TYPES, JPEG_MIME_TYPE, PNG_MIME_TYPE, PDF_MIME_TYPE, sequentialIncrementingNumberStringModelIdFactory, PDF_HEADER, PDF_EOF_MARKER, PDF_ENCRYPT_MARKER } from '@dereekb/util';
4
4
  import * as i1$2 from '@dereekb/dbx-core';
5
5
  import { completeOnDestroy, clean, AbstractTransitionWatcherDirective, DbxInjectionComponent, dbxActionWorkProgress, AbstractDbxButtonDirective, hasNonTrivialChildNodes, provideDbxButton, DbxCoreButtonModule, createInjectorForInjectionComponentConfig, initInjectionComponent, AbstractDbxActionValueGetterDirective, cleanSubscription, AbstractDbxActionHandlerDirective, FilterSourceDirective, provideActionStoreSource, isClickableFilterPreset, AbstractDbxAnchorDirective, expandClickableAnchorLinkTrees, DbxCoreFilterModule, DbxButton, DbxActionContextStoreSourceInstance, cleanSubscriptionWithLockSet, DBX_INJECTION_COMPONENT_DATA, checkNgContentWrapperHasContent, cleanLoadingContext, DbxActionSourceDirective, DbxActionSuccessHandlerDirective, DbxActionDirective, transformEmptyStringInputToUndefined, isIdleActionState, canTriggerAction, DbxCoreActionModule, DbxActionButtonDirective, onDbxAppAuth, SimpleStorageAccessorFactory, mergeStaticProviders, asSegueRef, AbstractTransitionDirective, DbxRouterService, AbstractIfDirective, isSegueRefActive, anchorTypeForAnchor } from '@dereekb/dbx-core';
6
6
  import { NgPopoverRef, NgOverlayContainerService } from 'ng-overlay-container';
@@ -17579,6 +17579,197 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
17579
17579
  }]
17580
17580
  }], propDecorators: { buttonElement: [{ type: i0.ViewChild, args: ['button', { ...{ read: ElementRef }, isSignal: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }] } });
17581
17581
 
17582
+ /**
17583
+ * Default JPEG quality used when re-encoding images during compression.
17584
+ */
17585
+ const DEFAULT_IMAGE_JPEG_QUALITY = 0.85;
17586
+ const PNG_EXTENSION = '.png';
17587
+ const JPG_EXTENSION = '.jpg';
17588
+ function isJpegMime(mimeType) {
17589
+ return JPEG_MIME_TYPES.includes(mimeType);
17590
+ }
17591
+ function decideEncodeTarget(sourceMimeType, convertPngToJpeg) {
17592
+ let mimeType;
17593
+ let extension;
17594
+ if (isJpegMime(sourceMimeType)) {
17595
+ mimeType = JPEG_MIME_TYPE;
17596
+ extension = JPG_EXTENSION;
17597
+ }
17598
+ else if (sourceMimeType === PNG_MIME_TYPE) {
17599
+ if (convertPngToJpeg) {
17600
+ mimeType = JPEG_MIME_TYPE;
17601
+ extension = JPG_EXTENSION;
17602
+ }
17603
+ else {
17604
+ mimeType = PNG_MIME_TYPE;
17605
+ extension = PNG_EXTENSION;
17606
+ }
17607
+ }
17608
+ else {
17609
+ // Unsupported source — let caller short-circuit.
17610
+ mimeType = sourceMimeType;
17611
+ extension = '';
17612
+ }
17613
+ return { mimeType, extension };
17614
+ }
17615
+ function computeScale(width, height, maxDimension) {
17616
+ let scale;
17617
+ if (maxDimension == null || maxDimension <= 0) {
17618
+ scale = 1;
17619
+ }
17620
+ else {
17621
+ const largest = Math.max(width, height);
17622
+ if (largest <= maxDimension) {
17623
+ scale = 1;
17624
+ }
17625
+ else {
17626
+ scale = maxDimension / largest;
17627
+ }
17628
+ }
17629
+ return scale;
17630
+ }
17631
+ /**
17632
+ * Default {@link ImageBitmapToBlobEncoder} that draws the bitmap onto an {@link OffscreenCanvas} (or `HTMLCanvasElement` fallback) and encodes to a blob via `convertToBlob` / `toBlob`.
17633
+ *
17634
+ * @param input - Bitmap and target dimensions to encode.
17635
+ * @returns A blob with the encoded image, or `null` if encoding failed.
17636
+ */
17637
+ const DEFAULT_IMAGE_BITMAP_TO_BLOB_ENCODER = async (input) => {
17638
+ const { bitmap, targetWidth, targetHeight, mimeType, quality } = input;
17639
+ let canvas;
17640
+ if (typeof OffscreenCanvas === 'undefined') {
17641
+ const htmlCanvas = document.createElement('canvas');
17642
+ htmlCanvas.width = targetWidth;
17643
+ htmlCanvas.height = targetHeight;
17644
+ canvas = htmlCanvas;
17645
+ }
17646
+ else {
17647
+ canvas = new OffscreenCanvas(targetWidth, targetHeight);
17648
+ }
17649
+ const ctx = canvas.getContext('2d');
17650
+ if (!ctx) {
17651
+ throw new Error('Failed to acquire 2D canvas context for image compression.');
17652
+ }
17653
+ ctx.drawImage(bitmap, 0, 0, targetWidth, targetHeight);
17654
+ let blob;
17655
+ if (typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas) {
17656
+ blob = await canvas.convertToBlob({ type: mimeType, quality });
17657
+ }
17658
+ else {
17659
+ blob = await new Promise((resolve) => {
17660
+ canvas.toBlob((b) => resolve(b), mimeType, quality);
17661
+ });
17662
+ }
17663
+ return blob;
17664
+ };
17665
+ function rewriteFileName(originalName, targetExtension) {
17666
+ let result;
17667
+ if (targetExtension === '') {
17668
+ result = originalName;
17669
+ }
17670
+ else {
17671
+ const lastDot = originalName.lastIndexOf('.');
17672
+ const base = lastDot >= 0 ? originalName.slice(0, lastDot) : originalName;
17673
+ result = `${base}${targetExtension}`;
17674
+ }
17675
+ return result;
17676
+ }
17677
+ function determineStatus(resized, converted) {
17678
+ let status;
17679
+ if (resized && converted) {
17680
+ status = 'resized_and_converted';
17681
+ }
17682
+ else if (resized) {
17683
+ status = 'resized';
17684
+ }
17685
+ else if (converted) {
17686
+ status = 'converted';
17687
+ }
17688
+ else {
17689
+ status = 'unchanged';
17690
+ }
17691
+ return status;
17692
+ }
17693
+ /**
17694
+ * Compresses an image `File` according to the supplied {@link DbxImageCompressionConfig}.
17695
+ *
17696
+ * Behavior:
17697
+ * - When the file is not a PNG/JPEG, or the config disables every compression path, returns the file unchanged.
17698
+ * - When the file fits inside `maxDimension` and no PNG→JPEG conversion is required, returns the file unchanged.
17699
+ * - Otherwise decodes via `createImageBitmap`, draws onto an {@link OffscreenCanvas} (or HTMLCanvasElement fallback), encodes the result using {@link DEFAULT_IMAGE_JPEG_QUALITY} or the configured `jpegQuality`, and wraps the blob into a new `File` with rewritten extension.
17700
+ * - Safety: if the encoded output is larger than the original, returns the original (compression is reported as `'unchanged'`).
17701
+ *
17702
+ * @param file - Source image file.
17703
+ * @param config - Compression configuration.
17704
+ * @param encoder - Optional injectable encoder used by tests to bypass real canvas APIs. Defaults to {@link DEFAULT_IMAGE_BITMAP_TO_BLOB_ENCODER}.
17705
+ * @returns Result describing the final file plus the {@link ImageCompressionStatus} for it.
17706
+ */
17707
+ async function compressImageFile(file, config, encoder = DEFAULT_IMAGE_BITMAP_TO_BLOB_ENCODER) {
17708
+ const mimeType = (file.type ?? '').toLowerCase();
17709
+ const maxDimension = config?.maxDimension;
17710
+ const convertPngToJpeg = config?.convertPngToJpeg ?? false;
17711
+ const jpegQuality = config?.jpegQuality ?? DEFAULT_IMAGE_JPEG_QUALITY;
17712
+ const minSizeBytes = config?.minSizeBytes;
17713
+ const isPng = mimeType === PNG_MIME_TYPE;
17714
+ const isJpeg = isJpegMime(mimeType);
17715
+ const isSupported = isPng || isJpeg;
17716
+ let result;
17717
+ const shouldConvertPng = isPng && convertPngToJpeg;
17718
+ if (!isSupported || config == null) {
17719
+ result = { file, mimeType: mimeType || file.type, compression: 'unchanged' };
17720
+ }
17721
+ else if ((maxDimension == null || maxDimension <= 0) && !shouldConvertPng) {
17722
+ // No-op config for this file.
17723
+ result = { file, mimeType, compression: 'unchanged' };
17724
+ }
17725
+ else if (minSizeBytes != null && file.size <= minSizeBytes && !shouldConvertPng) {
17726
+ // File is already small enough; skip when conversion is not required.
17727
+ result = { file, mimeType, compression: 'unchanged' };
17728
+ }
17729
+ else {
17730
+ result = await encodeCompressedImage({ file, mimeType, maxDimension, convertPngToJpeg, jpegQuality, isPng, encoder });
17731
+ }
17732
+ return result;
17733
+ }
17734
+ async function encodeCompressedImage(input) {
17735
+ const { file, mimeType, maxDimension, convertPngToJpeg, jpegQuality, isPng, encoder } = input;
17736
+ let bitmap = null;
17737
+ let result;
17738
+ try {
17739
+ bitmap = await createImageBitmap(file);
17740
+ const originalDimensions = { width: bitmap.width, height: bitmap.height };
17741
+ const scale = computeScale(bitmap.width, bitmap.height, maxDimension);
17742
+ const targetWidth = Math.max(1, Math.round(bitmap.width * scale));
17743
+ const targetHeight = Math.max(1, Math.round(bitmap.height * scale));
17744
+ const needsResize = scale < 1;
17745
+ const needsConvert = isPng && convertPngToJpeg;
17746
+ if (!needsResize && !needsConvert) {
17747
+ result = { file, mimeType, compression: 'unchanged', originalDimensions, finalDimensions: originalDimensions };
17748
+ }
17749
+ else {
17750
+ const target = decideEncodeTarget(mimeType, convertPngToJpeg);
17751
+ const blob = await encoder({ bitmap, targetWidth, targetHeight, mimeType: target.mimeType, quality: jpegQuality });
17752
+ result = buildEncodeResult({ blob, file, mimeType, originalDimensions, targetWidth, targetHeight, target, needsResize, needsConvert });
17753
+ }
17754
+ }
17755
+ finally {
17756
+ bitmap?.close?.();
17757
+ }
17758
+ return result;
17759
+ }
17760
+ function buildEncodeResult(input) {
17761
+ const { blob, file, mimeType, originalDimensions, targetWidth, targetHeight, target, needsResize, needsConvert } = input;
17762
+ if (blob == null || blob.size <= 0 || blob.size >= file.size) {
17763
+ // No blob, empty blob, or recompression grew the file; keep the original.
17764
+ return { file, mimeType, compression: 'unchanged', originalDimensions, finalDimensions: originalDimensions };
17765
+ }
17766
+ const nextName = needsConvert ? rewriteFileName(file.name, target.extension) : file.name;
17767
+ const nextFile = new File([blob], nextName, { type: target.mimeType, lastModified: file.lastModified });
17768
+ const status = determineStatus(needsResize, needsConvert);
17769
+ const finalDimensions = { width: targetWidth, height: targetHeight };
17770
+ return { file: nextFile, mimeType: target.mimeType, compression: status, originalDimensions, finalDimensions };
17771
+ }
17772
+
17582
17773
  /**
17583
17774
  * MIME types accepted by the PDF merge editor by default: PDF documents and PNG/JPEG images.
17584
17775
  */
@@ -17587,8 +17778,43 @@ const DEFAULT_PDF_MERGE_ACCEPT = [PDF_MIME_TYPE, PNG_MIME_TYPE, JPEG_MIME_TYPE];
17587
17778
  * MIME type emitted by the merged result blob.
17588
17779
  */
17589
17780
  const PDF_MERGE_RESULT_MIME_TYPE = PDF_MIME_TYPE;
17781
+ /**
17782
+ * Injection token for a workspace-wide default {@link DbxPdfMergeEditorConfig}. Use {@link provideDbxPdfMergeEditorConfig} to register a value.
17783
+ */
17784
+ const DBX_PDF_MERGE_EDITOR_CONFIG = new InjectionToken('DBX_PDF_MERGE_EDITOR_CONFIG');
17785
+ /**
17786
+ * Helper that returns a {@link Provider} binding {@link DBX_PDF_MERGE_EDITOR_CONFIG} to the given config value.
17787
+ *
17788
+ * @param config - Configuration to register.
17789
+ * @returns Provider entry suitable for inclusion in `providers`.
17790
+ */
17791
+ function provideDbxPdfMergeEditorConfig(config) {
17792
+ return { provide: DBX_PDF_MERGE_EDITOR_CONFIG, useValue: config };
17793
+ }
17590
17794
 
17591
17795
  const TEXT_DECODER = new TextDecoder('latin1');
17796
+ const FORMAT_KILOBYTE = 1024;
17797
+ const FORMAT_MEGABYTE = FORMAT_KILOBYTE * 1024;
17798
+ /**
17799
+ * Formats a byte count as a short human-readable string (`B` / `KB` / `MB`). Used by the merge editor banner and entry rows.
17800
+ *
17801
+ * @param size - Byte count to format.
17802
+ * @returns Human-readable string.
17803
+ * @__NO_SIDE_EFFECTS__
17804
+ */
17805
+ function formatPdfMergeEntrySize(size) {
17806
+ let result;
17807
+ if (size >= FORMAT_MEGABYTE) {
17808
+ result = `${(size / FORMAT_MEGABYTE).toFixed(1)} MB`;
17809
+ }
17810
+ else if (size >= FORMAT_KILOBYTE) {
17811
+ result = `${(size / FORMAT_KILOBYTE).toFixed(1)} KB`;
17812
+ }
17813
+ else {
17814
+ result = `${size} B`;
17815
+ }
17816
+ return result;
17817
+ }
17592
17818
  /**
17593
17819
  * Returns the {@link PdfMergeEntryKind} for a file based on its MIME type, with a small fallback to file-extension matching when the browser provided no MIME type.
17594
17820
  *
@@ -17632,15 +17858,40 @@ function resolvePdfMergeMimeType(file, kind) {
17632
17858
  * Default factory used to generate stable per-instance entry IDs.
17633
17859
  */
17634
17860
  const DEFAULT_ENTRY_ID_FACTORY = sequentialIncrementingNumberStringModelIdFactory();
17861
+ function buildEntryFromFile(input) {
17862
+ const { file, kind, original, compression, idFactory, slotId } = input;
17863
+ const nextEntry = {
17864
+ id: idFactory(),
17865
+ file,
17866
+ name: file.name,
17867
+ mimeType: resolvePdfMergeMimeType(file, kind),
17868
+ size: file.size,
17869
+ kind,
17870
+ status: 'validating',
17871
+ slotId,
17872
+ original,
17873
+ compression
17874
+ };
17875
+ nextEntry.validation = validatePdfMergeEntry(nextEntry);
17876
+ return nextEntry;
17877
+ }
17878
+ function originalFromFile(file, kind, dimensions) {
17879
+ return {
17880
+ name: file.name,
17881
+ mimeType: resolvePdfMergeMimeType(file, kind),
17882
+ size: file.size,
17883
+ dimensions
17884
+ };
17885
+ }
17635
17886
  /**
17636
- * Builds a {@link PdfMergeEntry} from a user-provided file, classifying its kind and assigning a fresh id. Returns `null` for unsupported file types so the caller can drop them.
17887
+ * Builds a {@link PdfMergeEntry} synchronously from a user-provided file, classifying its kind and assigning a fresh id. Skips image compression — callers that need it must use the async {@link buildPdfMergeEntry}. Returns `null` for unsupported file types so the caller can drop them.
17637
17888
  *
17638
17889
  * @param file - File the user added.
17639
- * @param config - Optional config for slot attribution and id factory override.
17890
+ * @param config - Optional config for slot attribution and id factory override. `imageCompression` is ignored here.
17640
17891
  * @returns The new entry with `validating` status, or `null` when the file is not a supported PDF/PNG/JPEG.
17641
17892
  * @__NO_SIDE_EFFECTS__
17642
17893
  */
17643
- function buildPdfMergeEntry(file, config) {
17894
+ function buildPdfMergeEntrySync(file, config) {
17644
17895
  const kind = classifyPdfMergeFile(file);
17645
17896
  const idFactory = config?.idFactory ?? DEFAULT_ENTRY_ID_FACTORY;
17646
17897
  const slotId = config?.slotId;
@@ -17649,18 +17900,35 @@ function buildPdfMergeEntry(file, config) {
17649
17900
  entry = null;
17650
17901
  }
17651
17902
  else {
17652
- const nextEntry = {
17653
- id: idFactory(),
17654
- file,
17655
- name: file.name,
17656
- mimeType: resolvePdfMergeMimeType(file, kind),
17657
- size: file.size,
17658
- kind,
17659
- status: 'validating',
17660
- slotId
17661
- };
17662
- nextEntry.validation = validatePdfMergeEntry(nextEntry);
17663
- entry = nextEntry;
17903
+ const original = originalFromFile(file, kind);
17904
+ entry = buildEntryFromFile({ file, kind, original, compression: 'unchanged', idFactory, slotId });
17905
+ }
17906
+ return entry;
17907
+ }
17908
+ /**
17909
+ * Builds a {@link PdfMergeEntry} from a user-provided file, classifying its kind and assigning a fresh id. For image files with an `imageCompression` config the source is downscaled and/or PNG→JPEG converted before the entry is constructed; the original file metadata is captured under {@link PdfMergeEntry.original} regardless. Returns `null` for unsupported file types so the caller can drop them.
17910
+ *
17911
+ * @param file - File the user added.
17912
+ * @param config - Optional config for slot attribution, id factory override, and image compression.
17913
+ * @returns The new entry with `validating` status, or `null` when the file is not a supported PDF/PNG/JPEG.
17914
+ */
17915
+ async function buildPdfMergeEntry(file, config) {
17916
+ const kind = classifyPdfMergeFile(file);
17917
+ const idFactory = config?.idFactory ?? DEFAULT_ENTRY_ID_FACTORY;
17918
+ const slotId = config?.slotId;
17919
+ const imageCompression = config?.imageCompression;
17920
+ let entry;
17921
+ if (kind == null) {
17922
+ entry = null;
17923
+ }
17924
+ else if (kind === 'image' && imageCompression != null) {
17925
+ const compressionResult = await compressImageFile(file, imageCompression);
17926
+ const original = originalFromFile(file, kind, compressionResult.originalDimensions);
17927
+ entry = buildEntryFromFile({ file: compressionResult.file, kind, original, compression: compressionResult.compression, idFactory, slotId });
17928
+ }
17929
+ else {
17930
+ const original = originalFromFile(file, kind);
17931
+ entry = buildEntryFromFile({ file, kind, original, compression: 'unchanged', idFactory, slotId });
17664
17932
  }
17665
17933
  return entry;
17666
17934
  }
@@ -17748,6 +18016,7 @@ const DBX_PDF_MERGE_EDITOR_INITIAL_STATE = {
17748
18016
  */
17749
18017
  class DbxPdfMergeEditorStore extends ComponentStore {
17750
18018
  _validator$ = new BehaviorSubject(undefined);
18019
+ _outputSizeLimit$ = new BehaviorSubject(undefined);
17751
18020
  constructor() {
17752
18021
  super(DBX_PDF_MERGE_EDITOR_INITIAL_STATE);
17753
18022
  }
@@ -17783,16 +18052,16 @@ class DbxPdfMergeEditorStore extends ComponentStore {
17783
18052
  */
17784
18053
  isValidating$ = this.entries$.pipe(map((entries) => entries.some((entry) => entry.status === 'validating')), distinctUntilChanged(), shareReplay(1));
17785
18054
  /**
17786
- * Emits the boolean output of the registered {@link DbxPdfMergeEditorValidator} delegate, or a constant `true` when no delegate is registered. {@link currentMergeOutput$} gates merge emissions on this stream.
18055
+ * Emits the boolean output of the registered {@link DbxPdfMergeEditorValidator} delegate, or a constant `true` when no delegate is registered. Composed with {@link sizeLimitValid$} into {@link isValid$} to gate {@link currentMergeOutput$}.
17787
18056
  */
17788
- isValid$ = this._validator$.pipe(switchMap((validator) => (validator ? validator(this.entries$) : of(true))), distinctUntilChanged(), shareReplay(1));
18057
+ validatorValid$ = this._validator$.pipe(switchMap((validator) => (validator ? validator(this.entries$) : of(true))), distinctUntilChanged(), shareReplay(1));
17789
18058
  /**
17790
- * Emits the merged PDF blob whenever every entry has finished validating (see {@link isValidating$}), at least one is `ready`, and the registered validator delegate (if any) reports `true`. Emits `undefined` while validation is in flight, when the list is empty, when the delegate reports invalid, or when the most recent merge failed. Multicast via {@link shareReplay} so multiple subscribers share a single merge.
18059
+ * Internal pre-validity merge stream produced without consulting {@link isValid$}. Drives both {@link outputSize$} and the eventual {@link currentMergeOutput$} so size-based gating can observe the would-be blob without creating a cycle.
17791
18060
  */
17792
- currentMergeOutput$ = combineLatest([this.entries$, this.isValidating$, this.isValid$]).pipe(switchMap(([entries, isValidating, isValid]) => {
18061
+ _candidateMergeOutput$ = combineLatest([this.entries$, this.isValidating$, this.validatorValid$]).pipe(switchMap(([entries, isValidating, validatorValid]) => {
17793
18062
  const hasReady = entries.some((entry) => entry.status === 'ready');
17794
18063
  let next$;
17795
- if (isValidating || !hasReady || !isValid) {
18064
+ if (isValidating || !hasReady || !validatorValid) {
17796
18065
  next$ = of(undefined);
17797
18066
  }
17798
18067
  else {
@@ -17800,6 +18069,31 @@ class DbxPdfMergeEditorStore extends ComponentStore {
17800
18069
  }
17801
18070
  return next$;
17802
18071
  }), shareReplay(1));
18072
+ /**
18073
+ * Emits the byte size of the most recent candidate merge output, or `undefined` while there is none.
18074
+ */
18075
+ outputSize$ = this._candidateMergeOutput$.pipe(map((blob) => blob?.size), distinctUntilChanged(), shareReplay(1));
18076
+ /**
18077
+ * Emits `true` while the candidate merge fits inside the active output-size limit (or when no limit is set). Cleared when the merge has not yet produced a blob — emits `true` in that case to avoid blocking the UI before there is anything to gate on.
18078
+ */
18079
+ sizeLimitValid$ = combineLatest([this._outputSizeLimit$, this.outputSize$]).pipe(map(([limit, size]) => {
18080
+ let valid;
18081
+ if (limit == null || size == null) {
18082
+ valid = true;
18083
+ }
18084
+ else {
18085
+ valid = size <= limit;
18086
+ }
18087
+ return valid;
18088
+ }), distinctUntilChanged(), shareReplay(1));
18089
+ /**
18090
+ * Emits `true` while both the registered {@link DbxPdfMergeEditorValidator} delegate (if any) and the optional output-size limit are satisfied. {@link currentMergeOutput$} gates merge emissions on this stream.
18091
+ */
18092
+ isValid$ = combineLatest([this.validatorValid$, this.sizeLimitValid$]).pipe(map(([validatorValid, sizeLimitValid]) => validatorValid && sizeLimitValid), distinctUntilChanged(), shareReplay(1));
18093
+ /**
18094
+ * Emits the merged PDF blob whenever every entry has finished validating (see {@link isValidating$}), at least one is `ready`, and {@link isValid$} reports `true`. Emits `undefined` while validation is in flight, when the list is empty, when the delegate or size limit reports invalid, or when the most recent merge failed.
18095
+ */
18096
+ currentMergeOutput$ = combineLatest([this._candidateMergeOutput$, this.sizeLimitValid$]).pipe(map(([blob, sizeLimitValid]) => (sizeLimitValid ? blob : undefined)), shareReplay(1));
17803
18097
  mergeOutput$ = this.currentMergeOutput$.pipe(filterMaybe());
17804
18098
  /**
17805
18099
  * Returns an observable of entries belonging to the given slot id. The result is filtered from {@link entries$} so the per-slot stream still reflects validation progress and removals.
@@ -17820,19 +18114,39 @@ class DbxPdfMergeEditorStore extends ComponentStore {
17820
18114
  this._validator$.next(validator);
17821
18115
  }
17822
18116
  /**
17823
- * Clears any registered validator delegate so {@link isValid$} returns to its default `true` stream.
18117
+ * Clears any registered validator delegate so {@link validatorValid$} returns to its default `true` stream.
17824
18118
  */
17825
18119
  clearValidator() {
17826
18120
  this._validator$.next(undefined);
17827
18121
  }
18122
+ /**
18123
+ * Sets the maximum allowed output blob size in bytes. When the candidate merge exceeds this limit, {@link sizeLimitValid$} (and therefore {@link isValid$}) emits `false` and {@link currentMergeOutput$} suppresses the blob. Pass `null`/`undefined` to clear the limit.
18124
+ *
18125
+ * @param maxBytes - Output byte ceiling, or a falsy value to remove the limit.
18126
+ */
18127
+ setOutputSizeLimit(maxBytes) {
18128
+ this._outputSizeLimit$.next(maxBytes ?? undefined);
18129
+ }
17828
18130
  // MARK: Updaters
17829
18131
  /**
17830
- * Builds {@link PdfMergeEntry} objects from the supplied files (skipping unsupported types) and appends them to state. Each entry's validation promise starts when the entry is built; {@link entries$} reflects each result as it resolves. When `input` is an object with a `slotId`, the resulting entries are tagged with that slot id.
18132
+ * Appends entries (already constructed) or builds them from raw files and appends them to state. Each entry's validation promise starts when the entry is built; {@link entries$} reflects each result as it resolves. When `input` is an object with `files` and `slotId`, the resulting entries are tagged with that slot id. When `input` is `{ entries }`, the entries are appended as-is — use this shape for entries that went through async client-side compression upstream.
17831
18133
  */
17832
18134
  addFiles = this.updater((state, input) => {
17833
- const files = Array.isArray(input) ? input : input.files;
17834
- const slotId = Array.isArray(input) ? undefined : input.slotId;
17835
- const newEntries = files.map((file) => buildPdfMergeEntry(file, { slotId })).filter((entry) => entry != null);
18135
+ let newEntries;
18136
+ if (Array.isArray(input)) {
18137
+ newEntries = input.map((file) => buildPdfMergeEntrySync(file)).filter((entry) => entry != null);
18138
+ }
18139
+ else {
18140
+ const objectInput = input;
18141
+ if (objectInput.entries == null) {
18142
+ const files = objectInput.files ?? [];
18143
+ const slotId = objectInput.slotId;
18144
+ newEntries = files.map((file) => buildPdfMergeEntrySync(file, { slotId })).filter((entry) => entry != null);
18145
+ }
18146
+ else {
18147
+ newEntries = [...objectInput.entries];
18148
+ }
18149
+ }
17836
18150
  return newEntries.length > 0 ? { ...state, rawEntries: [...state.rawEntries, ...newEntries] } : state;
17837
18151
  });
17838
18152
  removeEntry = this.updater((state, id) => ({ ...state, rawEntries: state.rawEntries.filter((entry) => entry.id !== id) }));
@@ -17890,21 +18204,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
17890
18204
  const PDF_ICON = 'picture_as_pdf';
17891
18205
  const IMAGE_ICON = 'image';
17892
18206
  const ERROR_ICON = 'error';
17893
- const KILOBYTE = 1024;
17894
- const MEGABYTE = KILOBYTE * 1024;
17895
- function formatPdfMergeEntrySize(size) {
17896
- let result;
17897
- if (size >= MEGABYTE) {
17898
- result = `${(size / MEGABYTE).toFixed(1)} MB`;
17899
- }
17900
- else if (size >= KILOBYTE) {
17901
- result = `${(size / KILOBYTE).toFixed(1)} KB`;
17902
- }
17903
- else {
17904
- result = `${size} B`;
17905
- }
17906
- return result;
17907
- }
17908
18207
  /**
17909
18208
  * Single row inside the {@link DbxPdfMergeListComponent}: shows the file's icon, name, formatted size, status, drag handle, and a remove button. The component's template is itself a `cdkDrag` element so each row can be reordered inside the parent's `cdkDropList`.
17910
18209
  */
@@ -17942,6 +18241,29 @@ class DbxPdfMergeEntryComponent {
17942
18241
  }
17943
18242
  return label;
17944
18243
  }, ...(ngDevMode ? [{ debugName: "statusLabelSignal" }] : /* istanbul ignore next */ []));
18244
+ compressionLabelSignal = computed(() => {
18245
+ const entry = this.entry();
18246
+ const compression = entry.compression;
18247
+ let label;
18248
+ if (compression === 'unchanged') {
18249
+ label = null;
18250
+ }
18251
+ else {
18252
+ const wasSize = formatPdfMergeEntrySize(entry.original.size);
18253
+ let prefix;
18254
+ if (compression === 'resized') {
18255
+ prefix = 'Resized';
18256
+ }
18257
+ else if (compression === 'converted') {
18258
+ prefix = 'Converted PNG → JPEG';
18259
+ }
18260
+ else {
18261
+ prefix = 'Resized + converted';
18262
+ }
18263
+ label = `${prefix} (was ${wasSize})`;
18264
+ }
18265
+ return label;
18266
+ }, ...(ngDevMode ? [{ debugName: "compressionLabelSignal" }] : /* istanbul ignore next */ []));
17945
18267
  onRemove() {
17946
18268
  this.store.removeEntry(this.entry().id);
17947
18269
  }
@@ -17959,6 +18281,9 @@ class DbxPdfMergeEntryComponent {
17959
18281
  <div class="dbx-pdf-merge-entry-name dbx-text-truncate" [title]="entry().name">{{ entry().name }}</div>
17960
18282
  <div class="dbx-pdf-merge-entry-meta dbx-hint dbx-small">
17961
18283
  <span>{{ sizeSignal() }}</span>
18284
+ @if (compressionLabelSignal(); as compressionLabel) {
18285
+ <span class="dbx-pdf-merge-entry-compression">{{ compressionLabel }}</span>
18286
+ }
17962
18287
  @if (statusLabelSignal(); as label) {
17963
18288
  <span class="dbx-pdf-merge-entry-status" [class.dbx-warn]="isErrorSignal()">{{ label }}</span>
17964
18289
  }
@@ -17990,6 +18315,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
17990
18315
  <div class="dbx-pdf-merge-entry-name dbx-text-truncate" [title]="entry().name">{{ entry().name }}</div>
17991
18316
  <div class="dbx-pdf-merge-entry-meta dbx-hint dbx-small">
17992
18317
  <span>{{ sizeSignal() }}</span>
18318
+ @if (compressionLabelSignal(); as compressionLabel) {
18319
+ <span class="dbx-pdf-merge-entry-compression">{{ compressionLabel }}</span>
18320
+ }
17993
18321
  @if (statusLabelSignal(); as label) {
17994
18322
  <span class="dbx-pdf-merge-entry-status" [class.dbx-warn]="isErrorSignal()">{{ label }}</span>
17995
18323
  }
@@ -18132,19 +18460,10 @@ const DEFAULT_DOWNLOAD_BUTTON = {
18132
18460
  display: { icon: 'download', text: 'Download' },
18133
18461
  style: { type: 'stroked' }
18134
18462
  };
18135
- /**
18136
- * Editor that lets the user collect PDFs and images, reorder them via drag-and-drop, and produce a single merged PDF for preview/download. Reads from an ancestor-provided {@link DbxPdfMergeEditorStore}. Optionally embeds a {@link DbxDownloadBlobButtonComponent} to offer a download affordance for the most recent merge.
18137
- *
18138
- * The parent view (or another directive) is responsible for providing {@link DbxPdfMergeEditorStore} so the editor and its peer components ({@link DbxPdfMergeListComponent}, {@link DbxPdfMergeEntryComponent}) share the same instance. Subscribe to the store's {@link DbxPdfMergeEditorStore.mergeOutput$} directly for downstream merge consumers.
18139
- *
18140
- * @example
18141
- * ```html
18142
- * <dbx-pdf-merge-editor [showDownloadButton]="true" fileName="receipts.pdf" [downloadButton]="{ display: { icon: 'cloud_download', text: 'Save' }, style: { type: 'flat', color: 'primary' } }"></dbx-pdf-merge-editor>
18143
- * ```
18144
- */
18145
18463
  class DbxPdfMergeEditorComponent {
18146
18464
  store = inject(DbxPdfMergeEditorStore);
18147
18465
  _matDialog = inject(MatDialog);
18466
+ _injectedConfig = inject(DBX_PDF_MERGE_EDITOR_CONFIG, { optional: true });
18148
18467
  /**
18149
18468
  * Single-slot subscription tracker for the deferred Preview path. Replacing the slot cancels any earlier in-flight wait so rapid clicks (or repeated programmatic calls) cannot stack pending dialogs.
18150
18469
  */
@@ -18163,7 +18482,26 @@ class DbxPdfMergeEditorComponent {
18163
18482
  * When `false`, hides the shared {@link DbxPdfMergeListComponent} below the slot content. Useful when each slot displays its owned files inline and you don't want a duplicate unified list.
18164
18483
  */
18165
18484
  showFileList = input(true, ...(ngDevMode ? [{ debugName: "showFileList" }] : /* istanbul ignore next */ []));
18485
+ /**
18486
+ * Optional configuration override for image compression and output-size limits. When omitted, falls back to the value provided via {@link DBX_PDF_MERGE_EDITOR_CONFIG} (if any).
18487
+ */
18488
+ config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : /* istanbul ignore next */ []));
18166
18489
  entriesChanged = output();
18490
+ /**
18491
+ * Merged config — the editor's own `config` input wins over the workspace-wide token.
18492
+ */
18493
+ effectiveConfigSignal = computed(() => {
18494
+ const fromInput = this.config();
18495
+ const fromToken = this._injectedConfig;
18496
+ return {
18497
+ imageCompression: fromInput?.imageCompression ?? fromToken?.imageCompression ?? null,
18498
+ outputSizeLimits: fromInput?.outputSizeLimits ?? fromToken?.outputSizeLimits ?? null
18499
+ };
18500
+ }, ...(ngDevMode ? [{ debugName: "effectiveConfigSignal" }] : /* istanbul ignore next */ []));
18501
+ imageCompressionConfigSignal = computed(() => this.effectiveConfigSignal().imageCompression, ...(ngDevMode ? [{ debugName: "imageCompressionConfigSignal" }] : /* istanbul ignore next */ []));
18502
+ outputSizeLimitsSignal = computed(() => this.effectiveConfigSignal().outputSizeLimits, ...(ngDevMode ? [{ debugName: "outputSizeLimitsSignal" }] : /* istanbul ignore next */ []));
18503
+ warnBytesSignal = computed(() => this.outputSizeLimitsSignal()?.warnBytes, ...(ngDevMode ? [{ debugName: "warnBytesSignal" }] : /* istanbul ignore next */ []));
18504
+ errorBytesSignal = computed(() => this.outputSizeLimitsSignal()?.errorBytes, ...(ngDevMode ? [{ debugName: "errorBytesSignal" }] : /* istanbul ignore next */ []));
18167
18505
  hasReadyEntriesSignal = toSignal(this.store.hasReadyEntries$, { initialValue: false });
18168
18506
  entryCountSignal = toSignal(this.store.entryCount$, { initialValue: 0 });
18169
18507
  /**
@@ -18181,6 +18519,41 @@ class DbxPdfMergeEditorComponent {
18181
18519
  * Latest merged blob (or `undefined` while validation/merge is in flight or no entries are ready). Sourced from {@link DbxPdfMergeEditorStore.currentMergeOutput$} so the download button always reflects the current merge without needing the user to click Preview first.
18182
18520
  */
18183
18521
  mergeBlobSignal = toSignal(this.store.currentMergeOutput$, { initialValue: undefined });
18522
+ /**
18523
+ * Latest candidate output size in bytes (sourced from {@link DbxPdfMergeEditorStore.outputSize$}). Drives the warning/error banner.
18524
+ */
18525
+ outputSizeSignal = toSignal(this.store.outputSize$, { initialValue: undefined });
18526
+ outputSizeStateSignal = computed(() => {
18527
+ const size = this.outputSizeSignal();
18528
+ const warnBytes = this.warnBytesSignal();
18529
+ const errorBytes = this.errorBytesSignal();
18530
+ let state;
18531
+ if (size == null) {
18532
+ state = 'ok';
18533
+ }
18534
+ else if (errorBytes != null && size > errorBytes) {
18535
+ state = 'error';
18536
+ }
18537
+ else if (warnBytes != null && size > warnBytes) {
18538
+ state = 'warn';
18539
+ }
18540
+ else {
18541
+ state = 'ok';
18542
+ }
18543
+ return state;
18544
+ }, ...(ngDevMode ? [{ debugName: "outputSizeStateSignal" }] : /* istanbul ignore next */ []));
18545
+ formattedOutputSizeSignal = computed(() => {
18546
+ const size = this.outputSizeSignal();
18547
+ return size == null ? null : formatPdfMergeEntrySize(size);
18548
+ }, ...(ngDevMode ? [{ debugName: "formattedOutputSizeSignal" }] : /* istanbul ignore next */ []));
18549
+ formattedWarnLimitSignal = computed(() => {
18550
+ const warnBytes = this.warnBytesSignal();
18551
+ return warnBytes == null ? null : formatPdfMergeEntrySize(warnBytes);
18552
+ }, ...(ngDevMode ? [{ debugName: "formattedWarnLimitSignal" }] : /* istanbul ignore next */ []));
18553
+ formattedErrorLimitSignal = computed(() => {
18554
+ const errorBytes = this.errorBytesSignal();
18555
+ return errorBytes == null ? null : formatPdfMergeEntrySize(errorBytes);
18556
+ }, ...(ngDevMode ? [{ debugName: "formattedErrorLimitSignal" }] : /* istanbul ignore next */ []));
18184
18557
  downloadConfigSignal = computed(() => ({
18185
18558
  blob: this.mergeBlobSignal(),
18186
18559
  fileName: this.fileName(),
@@ -18188,10 +18561,21 @@ class DbxPdfMergeEditorComponent {
18188
18561
  }), ...(ngDevMode ? [{ debugName: "downloadConfigSignal" }] : /* istanbul ignore next */ []));
18189
18562
  constructor() {
18190
18563
  this.store.entries$.pipe(takeUntilDestroyed()).subscribe((entries) => this.entriesChanged.emit(entries));
18564
+ effect(() => {
18565
+ const errorBytes = this.errorBytesSignal();
18566
+ this.store.setOutputSizeLimit(errorBytes);
18567
+ });
18191
18568
  }
18192
- onFiles(event) {
18193
- if (event.matchResult.accepted.length > 0) {
18194
- this.store.addFiles({ files: event.matchResult.accepted });
18569
+ async onFiles(event) {
18570
+ const accepted = event.matchResult.accepted;
18571
+ if (accepted.length === 0) {
18572
+ return;
18573
+ }
18574
+ const imageCompression = this.imageCompressionConfigSignal();
18575
+ const entries = await Promise.all(accepted.map((file) => buildPdfMergeEntry(file, { imageCompression })));
18576
+ const filtered = entries.filter((entry) => entry != null);
18577
+ if (filtered.length > 0) {
18578
+ this.store.addFiles({ entries: filtered });
18195
18579
  }
18196
18580
  }
18197
18581
  onClear() {
@@ -18223,14 +18607,14 @@ class DbxPdfMergeEditorComponent {
18223
18607
  });
18224
18608
  }
18225
18609
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DbxPdfMergeEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18226
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DbxPdfMergeEditorComponent, isStandalone: true, selector: "dbx-pdf-merge-editor", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, showDownloadButton: { classPropertyName: "showDownloadButton", publicName: "showDownloadButton", isSignal: true, isRequired: false, transformFunction: null }, showPreviewButton: { classPropertyName: "showPreviewButton", publicName: "showPreviewButton", isSignal: true, isRequired: false, transformFunction: null }, downloadButton: { classPropertyName: "downloadButton", publicName: "downloadButton", isSignal: true, isRequired: false, transformFunction: null }, showAddFiles: { classPropertyName: "showAddFiles", publicName: "showAddFiles", isSignal: true, isRequired: false, transformFunction: null }, showFileList: { classPropertyName: "showFileList", publicName: "showFileList", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entriesChanged: "entriesChanged" }, host: { classAttribute: "dbx-pdf-merge-editor d-block" }, ngImport: i0, template: "@if (showAddFiles()) {\n <div class=\"dbx-pdf-merge-editor-upload d-block dbx-mb3\">\n <dbx-file-upload [accept]=\"accept()\" [multiple]=\"multiple()\" (filesChanged)=\"onFiles($event)\" [hint]=\"'Drop PDFs or images here, or click to browse'\" [text]=\"'Add files'\" icon=\"upload_file\"></dbx-file-upload>\n </div>\n}\n<ng-content></ng-content>\n@if (showFileList()) {\n <dbx-pdf-merge-list></dbx-pdf-merge-list>\n}\n<div class=\"dbx-pdf-merge-editor-actions\">\n <span class=\"dbx-hint dbx-small\">{{ entryCountSignal() }} file(s)</span>\n <span class=\"dbx-spacer\"></span>\n <dbx-button text=\"Clear\" icon=\"delete\" [disabled]=\"entryCountSignal() === 0\" (buttonClick)=\"onClear()\"></dbx-button>\n @if (showPreviewButton()) {\n <dbx-button text=\"Preview\" icon=\"picture_as_pdf\" [disabled]=\"!canMergeSignal()\" (buttonClick)=\"onPreview()\"></dbx-button>\n }\n @if (showDownloadButton() && canMergeSignal()) {\n <dbx-download-blob-button [config]=\"downloadConfigSignal()\"></dbx-download-blob-button>\n }\n</div>\n", dependencies: [{ kind: "component", type: DbxButtonComponent, selector: "dbx-button", inputs: ["bar", "type", "buttonStyle", "color", "spinnerColor", "customButtonColor", "customTextColor", "customSpinnerColor", "basic", "tonal", "raised", "stroked", "flat", "iconOnly", "fab", "customContent", "allowClickPropagation", "mode"] }, { kind: "component", type: DbxFileUploadComponent, selector: "dbx-file-upload", inputs: ["config", "buttonStyle", "buttonDisplay", "mode", "text", "icon", "hint", "clickAreaToUpload"], outputs: ["filesChanged"] }, { kind: "component", type: DbxDownloadBlobButtonComponent, selector: "dbx-download-blob-button", inputs: ["config"] }, { kind: "component", type: DbxPdfMergeListComponent, selector: "dbx-pdf-merge-list" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
18610
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DbxPdfMergeEditorComponent, isStandalone: true, selector: "dbx-pdf-merge-editor", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, showDownloadButton: { classPropertyName: "showDownloadButton", publicName: "showDownloadButton", isSignal: true, isRequired: false, transformFunction: null }, showPreviewButton: { classPropertyName: "showPreviewButton", publicName: "showPreviewButton", isSignal: true, isRequired: false, transformFunction: null }, downloadButton: { classPropertyName: "downloadButton", publicName: "downloadButton", isSignal: true, isRequired: false, transformFunction: null }, showAddFiles: { classPropertyName: "showAddFiles", publicName: "showAddFiles", isSignal: true, isRequired: false, transformFunction: null }, showFileList: { classPropertyName: "showFileList", publicName: "showFileList", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entriesChanged: "entriesChanged" }, host: { classAttribute: "dbx-pdf-merge-editor d-block" }, ngImport: i0, template: "@if (showAddFiles()) {\n <div class=\"dbx-pdf-merge-editor-upload d-block dbx-mb3\">\n <dbx-file-upload [accept]=\"accept()\" [multiple]=\"multiple()\" (filesChanged)=\"onFiles($event)\" [hint]=\"'Drop PDFs or images here, or click to browse'\" [text]=\"'Add files'\" icon=\"upload_file\"></dbx-file-upload>\n </div>\n}\n<ng-content></ng-content>\n@if (showFileList()) {\n <dbx-pdf-merge-list></dbx-pdf-merge-list>\n}\n@switch (outputSizeStateSignal()) {\n @case ('warn') {\n <div class=\"dbx-pdf-merge-editor-size-warning\">\n <mat-icon>warning</mat-icon>\n <span>Merged file is {{ formattedOutputSizeSignal() }} \u2014 above the recommended {{ formattedWarnLimitSignal() }} limit.</span>\n </div>\n }\n @case ('error') {\n <div class=\"dbx-pdf-merge-editor-size-error\">\n <mat-icon>error</mat-icon>\n <span>Merged file is {{ formattedOutputSizeSignal() }}, exceeds the {{ formattedErrorLimitSignal() }} limit. Remove or compress files to continue.</span>\n </div>\n }\n}\n<div class=\"dbx-pdf-merge-editor-actions\">\n <span class=\"dbx-hint dbx-small\">{{ entryCountSignal() }} file(s)</span>\n <span class=\"dbx-spacer\"></span>\n <dbx-button text=\"Clear\" icon=\"delete\" [disabled]=\"entryCountSignal() === 0\" (buttonClick)=\"onClear()\"></dbx-button>\n @if (showPreviewButton()) {\n <dbx-button text=\"Preview\" icon=\"picture_as_pdf\" [disabled]=\"!canMergeSignal()\" (buttonClick)=\"onPreview()\"></dbx-button>\n }\n @if (showDownloadButton() && canMergeSignal()) {\n <dbx-download-blob-button [config]=\"downloadConfigSignal()\"></dbx-download-blob-button>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: DbxButtonComponent, selector: "dbx-button", inputs: ["bar", "type", "buttonStyle", "color", "spinnerColor", "customButtonColor", "customTextColor", "customSpinnerColor", "basic", "tonal", "raised", "stroked", "flat", "iconOnly", "fab", "customContent", "allowClickPropagation", "mode"] }, { kind: "component", type: DbxFileUploadComponent, selector: "dbx-file-upload", inputs: ["config", "buttonStyle", "buttonDisplay", "mode", "text", "icon", "hint", "clickAreaToUpload"], outputs: ["filesChanged"] }, { kind: "component", type: DbxDownloadBlobButtonComponent, selector: "dbx-download-blob-button", inputs: ["config"] }, { kind: "component", type: DbxPdfMergeListComponent, selector: "dbx-pdf-merge-list" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
18227
18611
  }
18228
18612
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DbxPdfMergeEditorComponent, decorators: [{
18229
18613
  type: Component,
18230
18614
  args: [{ selector: 'dbx-pdf-merge-editor', host: {
18231
18615
  class: 'dbx-pdf-merge-editor d-block'
18232
- }, imports: [DbxButtonComponent, DbxFileUploadComponent, DbxDownloadBlobButtonComponent, DbxPdfMergeListComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "@if (showAddFiles()) {\n <div class=\"dbx-pdf-merge-editor-upload d-block dbx-mb3\">\n <dbx-file-upload [accept]=\"accept()\" [multiple]=\"multiple()\" (filesChanged)=\"onFiles($event)\" [hint]=\"'Drop PDFs or images here, or click to browse'\" [text]=\"'Add files'\" icon=\"upload_file\"></dbx-file-upload>\n </div>\n}\n<ng-content></ng-content>\n@if (showFileList()) {\n <dbx-pdf-merge-list></dbx-pdf-merge-list>\n}\n<div class=\"dbx-pdf-merge-editor-actions\">\n <span class=\"dbx-hint dbx-small\">{{ entryCountSignal() }} file(s)</span>\n <span class=\"dbx-spacer\"></span>\n <dbx-button text=\"Clear\" icon=\"delete\" [disabled]=\"entryCountSignal() === 0\" (buttonClick)=\"onClear()\"></dbx-button>\n @if (showPreviewButton()) {\n <dbx-button text=\"Preview\" icon=\"picture_as_pdf\" [disabled]=\"!canMergeSignal()\" (buttonClick)=\"onPreview()\"></dbx-button>\n }\n @if (showDownloadButton() && canMergeSignal()) {\n <dbx-download-blob-button [config]=\"downloadConfigSignal()\"></dbx-download-blob-button>\n }\n</div>\n" }]
18233
- }], ctorParameters: () => [], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], showDownloadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDownloadButton", required: false }] }], showPreviewButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPreviewButton", required: false }] }], downloadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadButton", required: false }] }], showAddFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddFiles", required: false }] }], showFileList: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFileList", required: false }] }], entriesChanged: [{ type: i0.Output, args: ["entriesChanged"] }] } });
18616
+ }, imports: [MatIconModule, DbxButtonComponent, DbxFileUploadComponent, DbxDownloadBlobButtonComponent, DbxPdfMergeListComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "@if (showAddFiles()) {\n <div class=\"dbx-pdf-merge-editor-upload d-block dbx-mb3\">\n <dbx-file-upload [accept]=\"accept()\" [multiple]=\"multiple()\" (filesChanged)=\"onFiles($event)\" [hint]=\"'Drop PDFs or images here, or click to browse'\" [text]=\"'Add files'\" icon=\"upload_file\"></dbx-file-upload>\n </div>\n}\n<ng-content></ng-content>\n@if (showFileList()) {\n <dbx-pdf-merge-list></dbx-pdf-merge-list>\n}\n@switch (outputSizeStateSignal()) {\n @case ('warn') {\n <div class=\"dbx-pdf-merge-editor-size-warning\">\n <mat-icon>warning</mat-icon>\n <span>Merged file is {{ formattedOutputSizeSignal() }} \u2014 above the recommended {{ formattedWarnLimitSignal() }} limit.</span>\n </div>\n }\n @case ('error') {\n <div class=\"dbx-pdf-merge-editor-size-error\">\n <mat-icon>error</mat-icon>\n <span>Merged file is {{ formattedOutputSizeSignal() }}, exceeds the {{ formattedErrorLimitSignal() }} limit. Remove or compress files to continue.</span>\n </div>\n }\n}\n<div class=\"dbx-pdf-merge-editor-actions\">\n <span class=\"dbx-hint dbx-small\">{{ entryCountSignal() }} file(s)</span>\n <span class=\"dbx-spacer\"></span>\n <dbx-button text=\"Clear\" icon=\"delete\" [disabled]=\"entryCountSignal() === 0\" (buttonClick)=\"onClear()\"></dbx-button>\n @if (showPreviewButton()) {\n <dbx-button text=\"Preview\" icon=\"picture_as_pdf\" [disabled]=\"!canMergeSignal()\" (buttonClick)=\"onPreview()\"></dbx-button>\n }\n @if (showDownloadButton() && canMergeSignal()) {\n <dbx-download-blob-button [config]=\"downloadConfigSignal()\"></dbx-download-blob-button>\n }\n</div>\n" }]
18617
+ }], ctorParameters: () => [], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], showDownloadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDownloadButton", required: false }] }], showPreviewButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPreviewButton", required: false }] }], downloadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadButton", required: false }] }], showAddFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddFiles", required: false }] }], showFileList: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFileList", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], entriesChanged: [{ type: i0.Output, args: ["entriesChanged"] }] } });
18234
18618
 
18235
18619
  /**
18236
18620
  * Directive that registers as the active {@link DbxPdfMergeEditorValidator} on a {@link DbxPdfMergeEditorStore} and gates merge emissions on the readiness of every registered slot. {@link DbxPdfMergeEditorFileUploadComponent} instances walk the injector tree, find this directive, and call {@link registerSlot}/{@link unregisterSlot} during their own lifecycle.
@@ -18318,6 +18702,7 @@ const DEFAULT_REQUIRED = true;
18318
18702
  class DbxPdfMergeEditorFileUploadComponent {
18319
18703
  store = inject(DbxPdfMergeEditorStore);
18320
18704
  _validator = inject(DbxPdfMergeEditorFileUploadValidatorDirective, { optional: true });
18705
+ _injectedConfig = inject(DBX_PDF_MERGE_EDITOR_CONFIG, { optional: true });
18321
18706
  slotId = input.required(...(ngDevMode ? [{ debugName: "slotId" }] : /* istanbul ignore next */ []));
18322
18707
  config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : /* istanbul ignore next */ []));
18323
18708
  acceptSignal = computed(() => this.config()?.accept ?? DEFAULT_PDF_MERGE_ACCEPT, ...(ngDevMode ? [{ debugName: "acceptSignal" }] : /* istanbul ignore next */ []));
@@ -18418,7 +18803,11 @@ class DbxPdfMergeEditorFileUploadComponent {
18418
18803
  currentIndex: event.currentIndex
18419
18804
  });
18420
18805
  }
18421
- onFiles(event) {
18806
+ /**
18807
+ * Resolves the active image compression config: per-slot override → workspace-wide DI token. The intermediate ancestor {@link DbxPdfMergeEditorComponent} config is not visible from a slot, so consumers needing per-editor compression should either set the slot's `imageCompression` directly or rely on the injection token.
18808
+ */
18809
+ effectiveImageCompressionSignal = computed(() => this.config()?.imageCompression ?? this._injectedConfig?.imageCompression ?? null, ...(ngDevMode ? [{ debugName: "effectiveImageCompressionSignal" }] : /* istanbul ignore next */ []));
18810
+ async onFiles(event) {
18422
18811
  const accepted = event.matchResult.accepted;
18423
18812
  const ownedCount = this.ownedEntriesSignal().length;
18424
18813
  const capacity = this.capacitySignal();
@@ -18433,8 +18822,15 @@ class DbxPdfMergeEditorFileUploadComponent {
18433
18822
  else {
18434
18823
  filesToAdd = accepted;
18435
18824
  }
18436
- if (filesToAdd.length > 0) {
18437
- this.store.addFiles({ files: filesToAdd, slotId: this.slotId() });
18825
+ if (filesToAdd.length === 0) {
18826
+ return;
18827
+ }
18828
+ const slotId = this.slotId();
18829
+ const imageCompression = this.effectiveImageCompressionSignal();
18830
+ const entries = await Promise.all(filesToAdd.map((file) => buildPdfMergeEntry(file, { slotId, imageCompression })));
18831
+ const filtered = entries.filter((entry) => entry != null);
18832
+ if (filtered.length > 0) {
18833
+ this.store.addFiles({ entries: filtered });
18438
18834
  }
18439
18835
  }
18440
18836
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DbxPdfMergeEditorFileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -18606,5 +19002,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
18606
19002
  * Generated bundle index. Do not edit.
18607
19003
  */
18608
19004
 
18609
- export { APP_POPUP_MINIMIZED_WIDTH, APP_POPUP_NORMAL_HEIGHT, APP_POPUP_NORMAL_WIDTH, AbstractDbxClipboardDirective, AbstractDbxErrorWidgetComponent, AbstractDbxFileUploadComponent, AbstractDbxHelpWidgetDirective, AbstractDbxListAccordionViewDirective, AbstractDbxListGridViewDirective, AbstractDbxListViewDirective, AbstractDbxListWrapperDirective, AbstractDbxPartialPresetFilterMenuDirective, AbstractDbxSegueAnchorDirective, AbstractDbxSelectionListViewDirective, AbstractDbxSelectionListWrapperDirective, AbstractDbxValueListItemModifierDirective, AbstractDbxValueListViewDirective, AbstractDbxValueListViewItemComponent, AbstractDbxWidgetComponent, AbstractDialogDirective, AbstractFilterPopoverButtonDirective, AbstractPopoverDirective, AbstractPopoverRefDirective, AbstractPopoverRefWithEventsDirective, AbstractPopupDirective, AbstractPromptConfirmDirective, CompactContextStore, CompactMode, DBX_ACTION_SNACKBAR_DEFAULTS, DBX_ACTION_SNACKBAR_SERVICE_CONFIG, DBX_AVATAR_CONTEXT_DATA_TOKEN, DBX_COLOR_CUSTOM_BG_CSS_CLASS, DBX_COLOR_CUSTOM_TEXT_CSS_CLASS, DBX_DARK_STYLE_CLASS_SUFFIX, DBX_HELP_WIDGET_ENTRY_DATA_TOKEN, DBX_LIST_ACCORDION_VIEW_COMPONENT_IMPORTS_AND_EXPORTS, DBX_LIST_GRID_VIEW_COMPONENT_IMPORTS_AND_EXPORTS, DBX_LIST_ITEM_DISABLE_RIPPLE_LIST_ITEM_MODIFIER_KEY, DBX_LIST_ITEM_IS_SELECTED_ITEM_MODIFIER_KEY, DBX_MODEL_VIEW_TRACKER_STORAGE_ACCESSOR_TOKEN, DBX_PDF_MERGE_EDITOR_INITIAL_STATE, DBX_PROGRESS_BUTTON_GLOBAL_CONFIG, DBX_ROUTER_ANCHOR_COMPONENTS, DBX_ROUTER_VALUE_LIST_ITEM_MODIFIER_KEY, DBX_THEME_COLORS, DBX_THEME_COLORS_EXTRA, DBX_THEME_COLORS_EXTRA_SECONDARY, DBX_THEME_COLORS_MAIN, DBX_VALUE_LIST_VIEW_ITEM, DBX_WEB_FILE_PREVIEW_SERVICE_ENTRIES_TOKEN, DBX_WEB_FILE_PREVIEW_SERVICE_ZIP_COMPONENT_PRESET, DBX_WEB_FILE_PREVIEW_SERVICE_ZIP_PRESET_ENTRY, DBX_WEB_PAGE_TITLE_SERVICE_CONFIG, DEFAULT_DBX_CHIP_TONE, DEFAULT_DBX_DETACH_KEY, DEFAULT_DBX_ERROR_SNACKBAR_CONFIG, DEFAULT_DBX_HELP_VIEW_POPOVER_KEY, DEFAULT_DBX_LINKIFY_STRING_TYPE, DEFAULT_DBX_LIST_ACCORDION_VIEW_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_LIST_GRID_VIEW_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_LIST_ITEM_DISABLE_FUNCTION, DEFAULT_DBX_LIST_ITEM_IS_SELECTED_FUNCTION, DEFAULT_DBX_LIST_SCROLL_DISTANCE, DEFAULT_DBX_LIST_THROTTLE_SCROLL, DEFAULT_DBX_LIST_VIEW_META_ICON, DEFAULT_DBX_PROMPT_CONFIRM_DIALOG_CONFIG, DEFAULT_DBX_SELECTION_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_SIDENAV_MENU_ICON, DEFAULT_DBX_STYLE_CONFIG_TOKEN, DEFAULT_DBX_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_WEB_FILE_PREVIEW_SERVICE_DIALOG_WITH_COMPONENT_FUNCTION, DEFAULT_DBX_WEB_FILE_PREVIEW_SERVICE_PREVIEW_COMPONENT_FUNCTION, DEFAULT_ERROR_POPOVER_KEY, DEFAULT_ERROR_WIDGET_CODE, DEFAULT_FILTER_POPOVER_KEY, DEFAULT_LIST_GRID_SIZE_CONFIG, DEFAULT_LIST_WRAPPER_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_LOADING_PROGRESS_DIAMETER, DEFAULT_PDF_MERGE_ACCEPT, DEFAULT_SCREEN_MEDIA_SERVICE_CONFIG, DEFAULT_SNACKBAR_DIRECTIVE_DURATION, DEFAULT_TWO_COLUMNS_MIN_RIGHT_WIDTH, DEFAULT_VALUE_LIST_VIEW_CONTENT_COMPONENT_TRACK_BY_FUNCTION, DbxAccordionHeaderHeightDirective, DbxActionConfirmDirective, DbxActionDialogDirective, DbxActionErrorDirective, DbxActionKeyTriggerDirective, DbxActionLoadingContextDirective, DbxActionModule, DbxActionPopoverDirective, DbxActionSnackbarComponent, DbxActionSnackbarDirective, DbxActionSnackbarErrorDirective, DbxActionSnackbarModule, DbxActionSnackbarService, DbxActionTransitionSafetyDirective, DbxActionUIRouterTransitionSafetyDialogComponent, DbxAnchorComponent, DbxAnchorContentComponent, DbxAnchorIconComponent, DbxAnchorListComponent, DbxAngularRouterSegueAnchorComponent, DbxAvatarComponent, DbxAvatarViewService, DbxAvatarViewServiceConfig, DbxBarDirective, DbxBarHeaderComponent, DbxBarLayoutModule, DbxBasicLoadingComponent, DbxBodyDirective, DbxButtonComponent, DbxButtonModule, DbxButtonSpacerDirective, DbxCardBoxComponent, DbxCardBoxContainerDirective, DbxCardBoxLayoutModule, DbxChipDirective, DbxChipListComponent, DbxClickToCopyTextComponent, DbxClickToCopyTextDirective, DbxColorDirective, DbxColorService, DbxColorServiceConfig, DbxColumnLayoutModule, DbxCompactDirective, DbxCompactLayoutModule, DbxContentBorderDirective, DbxContentBoxDirective, DbxContentContainerDirective, DbxContentDirective, DbxContentElevateDirective, DbxContentLayoutModule, DbxContentPageDirective, DbxContentPitDirective, DbxDetachContentComponent, DbxDetachControlButtonsComponent, DbxDetachController, DbxDetachControlsComponent, DbxDetachInitDirective, DbxDetachInteractionModule, DbxDetachOutletComponent, DbxDetachOverlayComponent, DbxDetachService, DbxDetachWindowState, DbxDetailBlockComponent, DbxDetailBlockHeaderComponent, DbxDialogContentCloseComponent, DbxDialogContentDirective, DbxDialogContentFooterComponent, DbxDialogInteractionModule, DbxDialogModule, DbxDownloadBlobButtonComponent, DbxDownloadTextViewComponent, DbxEmbedComponent, DbxErrorComponent, DbxErrorDefaultErrorWidgetComponent, DbxErrorDetailsComponent, DbxErrorPopoverComponent, DbxErrorSnackbarComponent, DbxErrorSnackbarService, DbxErrorViewComponent, DbxErrorWidgetService, DbxErrorWidgetViewComponent, DbxFileUploadActionCompatable, DbxFileUploadActionSyncDirective, DbxFileUploadAreaComponent, DbxFileUploadButtonComponent, DbxFileUploadComponent, DbxFilterInteractionModule, DbxFilterPopoverButtonComponent, DbxFilterPopoverComponent, DbxFilterWrapperComponent, DbxFlagComponent, DbxFlagLayoutModule, DbxFlagPromptComponent, DbxFlexGroupDirective, DbxFlexLayoutModule, DbxFlexSizeDirective, DbxHelpContextDirective, DbxHelpContextService, DbxHelpViewListComponent, DbxHelpViewListEntryComponent, DbxHelpViewPopoverButtonComponent, DbxHelpViewPopoverComponent, DbxHelpWidgetService, DbxHelpWidgetServiceConfig, DbxIconButtonComponent, DbxIconButtonModule, DbxIconItemComponent, DbxIconSpacerDirective, DbxIconTileComponent, DbxIconTileDirective, DbxIfSidenavDisplayModeDirective, DbxIframeComponent, DbxInjectionDialogComponent, DbxInteractionModule, DbxIntroActionSectionComponent, DbxLabelBlockComponent, DbxLayoutModule, DbxLinkComponent, DbxLinkifyComponent, DbxLinkifyService, DbxLinkifyServiceConfig, DbxListAccordionViewComponentImportsModule, DbxListComponent, DbxListEmptyContentComponent, DbxListGridViewComponentImportsModule, DbxListInternalContentDirective, DbxListItemAnchorModifierDirective, DbxListItemDisableRippleModifierDirective, DbxListItemIsSelectedModifierDirective, DbxListModifierModule, DbxListModule, DbxListTitleGroupDirective, DbxListView, DbxListViewMetaIconComponent, DbxListViewWrapper, DbxListWrapperComponentImportsModule, DbxLoadingComponent, DbxLoadingErrorDirective, DbxLoadingModule, DbxLoadingProgressComponent, DbxModelObjectStateService, actions as DbxModelStateActions, model_actions as DbxModelStateModelActions, DbxModelTrackerService, DbxModelTypesService, DbxModelViewTrackerStorage, DbxNavbarComponent, DbxNumberWithLimitComponent, DbxOneColumnComponent, DbxOneColumnLayoutModule, DbxPagebarComponent, DbxPartialPresetFilterListComponent, DbxPartialPresetFilterMenuComponent, DbxPdfMergeEditorComponent, DbxPdfMergeEditorFileUploadComponent, DbxPdfMergeEditorFileUploadHasStateDirective, DbxPdfMergeEditorFileUploadValidatorDirective, DbxPdfMergeEditorStore, DbxPdfMergeEntryComponent, DbxPdfMergeListComponent, DbxPdfPreviewComponent, DbxPopoverCloseButtonComponent, DbxPopoverComponent, DbxPopoverComponentController, DbxPopoverContentComponent, DbxPopoverController, DbxPopoverControlsDirective, DbxPopoverCoordinatorComponent, DbxPopoverCoordinatorService, DbxPopoverHeaderComponent, DbxPopoverInteractionContentModule, DbxPopoverInteractionModule, DbxPopoverScrollContentDirective, DbxPopoverService, DbxPopupComponent, DbxPopupComponentController, DbxPopupContentComponent, DbxPopupControlButtonsComponent, DbxPopupController, DbxPopupControlsComponent, DbxPopupCoordinatorComponent, DbxPopupCoordinatorService, DbxPopupInteractionModule, DbxPopupService, DbxPopupWindowState, DbxPresetFilterListComponent, DbxPresetFilterMenuComponent, DbxProgressBarButtonComponent, DbxProgressButtonsModule, DbxProgressSpinnerButtonComponent, DbxPromptBoxDirective, DbxPromptComponent, DbxPromptConfirm, DbxPromptConfirmButtonDirective, DbxPromptConfirmComponent, DbxPromptConfirmDialogComponent, DbxPromptConfirmDirective, DbxPromptModule, DbxPromptPageComponent, DbxReadableErrorModule, DbxResizedDirective, DbxRouterAnchorModule, DbxRouterLayoutModule, DbxRouterSidenavModule, DbxRouterWebProviderConfig, DbxScreenMediaService, DbxScreenMediaServiceConfig, DbxSectionComponent, DbxSectionHeaderComponent, DbxSectionLayoutModule, DbxSectionPageComponent, DbxSelectionValueListViewComponent, DbxSelectionValueListViewComponentImportsModule, DbxSelectionValueListViewContentComponent, DbxSetStyleDirective, DbxSidenavButtonComponent, DbxSidenavComponent, DbxSidenavPageComponent, DbxSidenavPagebarComponent, DbxSpacerDirective, DbxStepBlockComponent, DbxStructureDirective, DbxStructureModule, DbxStyleBodyDirective, DbxStyleDirective, DbxStyleLayoutModule, DbxStyleService, DbxSubSectionComponent, DbxTextChipsComponent, DbxTextColorDirective, DbxTextModule, DbxTwoBlockComponent, DbxTwoColumnBackDirective, DbxTwoColumnColumnHeadDirective, DbxTwoColumnComponent, DbxTwoColumnContextDirective, DbxTwoColumnFullLeftDirective, DbxTwoColumnLayoutModule, DbxTwoColumnRightComponent, DbxTwoColumnSrefDirective, DbxTwoColumnSrefShowRightDirective, DbxUIRouterSegueAnchorComponent, DbxUnitedStatesAddressComponent, DbxValueListAccordionViewComponent, DbxValueListAccordionViewContentComponent, DbxValueListAccordionViewContentGroupComponent, DbxValueListGridSizeDirective, DbxValueListGridViewComponent, DbxValueListGridViewContentComponent, DbxValueListGridViewContentGroupComponent, DbxValueListItemModifier, DbxValueListItemModifierDirective, DbxValueListView, DbxValueListViewComponent, DbxValueListViewComponentImportsModule, DbxValueListViewContentComponent, DbxValueListViewContentGroupComponent, DbxValueListViewGroupDelegate, DbxWebFilePreviewComponent, DbxWebFilePreviewService, DbxWebModule, DbxWebPageTitleInfoDirective, DbxWebPageTitleService, DbxWidgetListGridComponent, DbxWidgetListGridViewComponent, DbxWidgetListGridViewItemComponent, DbxWidgetService, DbxWidgetViewComponent, DbxWindowKeyDownListenerDirective, DbxZipBlobPreviewComponent, DbxZipPreviewComponent, PDF_MERGE_RESULT_MIME_TYPE, PopoverPositionStrategy, PopupGlobalPositionStrategy, SCREEN_MEDIA_WIDTH_TYPE_SIZE_MAP, SIDE_NAV_DISPLAY_MODE_ORDER, SideNavDisplayMode, TRACK_BY_MODEL_ID, TRACK_BY_MODEL_KEY, TwoColumnsContextStore, UNKNOWN_ERROR_WIDGET_CODE, addConfigToValueListItems, allDbxModelViewTrackerEventModelKeys, allDbxModelViewTrackerEventSetModelKeys, buildPdfMergeEntry, catchErrorServerParams, classifyPdfMergeFile, compactModeFromInput, compareScreenMediaWidthTypes, convertServerErrorParams, convertToPOJOServerErrorResponse, convertToServerErrorResponse, copyToClipboardFunction, dbxColorBackground, dbxListAccordionViewComponentImportsAndExports, dbxListGridViewComponentImportsAndExports, dbxPresetFilterMenuButtonIconObservable, dbxPresetFilterMenuButtonTextObservable, dbxStyleClassCleanSuffix, dbxThemeColorCssToken, dbxThemeColorCssTokenVar, dbxThemeColorCssVariable, dbxThemeColorCssVariableVar, dbxValueListItemDecisionFunction, dbxValueListItemKeyForItemValue, dbxWebDefaultPageTitleDelegate, dbxZipBlobPreviewEntryTreeFromEntries, defaultDbxModelViewTrackerStorageAccessorFactory, defaultDbxValueListViewGroupDelegate, defaultDbxValueListViewGroupValuesFunction, disableRightClickInCdkBackdrop, fileAcceptFilterTypeStringArray, fileAcceptFunction, fileAcceptString, fileArrayAcceptMatchFunction, flattenAccordionGroups, index as fromDbxModel, injectCopyToClipboardFunction, injectCopyToClipboardFunctionWithSnackbarMessage, isDbxColorConfig, listItemModifier, makeDbxActionSnackbarDisplayConfigGeneratorFunction, mapCompactModeObs, mapValuesToValuesListItemConfigObs, mergePdfMergeEntries, index$1 as onDbxModel, openEmbedDialog, openIframeDialog, openPdfPreviewDialog, openZipPreviewDialog, overrideClickElementEffect, provideDbxDetachController, provideDbxFileUploadActionCompatable, provideDbxHelpServices, provideDbxLinkify, provideDbxListView, provideDbxListViewWrapper, provideDbxModelService, provideDbxProgressButtonGlobalConfig, provideDbxPromptConfirm, provideDbxRouterWebAngularRouterProviderConfig, provideDbxRouterWebUiRouterProviderConfig, provideDbxScreenMediaService, provideDbxStyleService, provideDbxValueListView, provideDbxValueListViewGroupDelegate, provideDbxValueListViewModifier, provideDbxWebFilePreviewServiceEntries, provideDbxWebPageTitleService, provideTwoColumnsContext, registerHelpContextKeysWithDbxHelpContextService, resizeSignal, resolveSideNavDisplayMode, sanitizeDbxDialogContentConfig, screenMediaWidthTypeIsActive, trackByModelKeyRef, trackByUniqueIdentifier, validatePdfMergeEntry };
19005
+ export { APP_POPUP_MINIMIZED_WIDTH, APP_POPUP_NORMAL_HEIGHT, APP_POPUP_NORMAL_WIDTH, AbstractDbxClipboardDirective, AbstractDbxErrorWidgetComponent, AbstractDbxFileUploadComponent, AbstractDbxHelpWidgetDirective, AbstractDbxListAccordionViewDirective, AbstractDbxListGridViewDirective, AbstractDbxListViewDirective, AbstractDbxListWrapperDirective, AbstractDbxPartialPresetFilterMenuDirective, AbstractDbxSegueAnchorDirective, AbstractDbxSelectionListViewDirective, AbstractDbxSelectionListWrapperDirective, AbstractDbxValueListItemModifierDirective, AbstractDbxValueListViewDirective, AbstractDbxValueListViewItemComponent, AbstractDbxWidgetComponent, AbstractDialogDirective, AbstractFilterPopoverButtonDirective, AbstractPopoverDirective, AbstractPopoverRefDirective, AbstractPopoverRefWithEventsDirective, AbstractPopupDirective, AbstractPromptConfirmDirective, CompactContextStore, CompactMode, DBX_ACTION_SNACKBAR_DEFAULTS, DBX_ACTION_SNACKBAR_SERVICE_CONFIG, DBX_AVATAR_CONTEXT_DATA_TOKEN, DBX_COLOR_CUSTOM_BG_CSS_CLASS, DBX_COLOR_CUSTOM_TEXT_CSS_CLASS, DBX_DARK_STYLE_CLASS_SUFFIX, DBX_HELP_WIDGET_ENTRY_DATA_TOKEN, DBX_LIST_ACCORDION_VIEW_COMPONENT_IMPORTS_AND_EXPORTS, DBX_LIST_GRID_VIEW_COMPONENT_IMPORTS_AND_EXPORTS, DBX_LIST_ITEM_DISABLE_RIPPLE_LIST_ITEM_MODIFIER_KEY, DBX_LIST_ITEM_IS_SELECTED_ITEM_MODIFIER_KEY, DBX_MODEL_VIEW_TRACKER_STORAGE_ACCESSOR_TOKEN, DBX_PDF_MERGE_EDITOR_CONFIG, DBX_PDF_MERGE_EDITOR_INITIAL_STATE, DBX_PROGRESS_BUTTON_GLOBAL_CONFIG, DBX_ROUTER_ANCHOR_COMPONENTS, DBX_ROUTER_VALUE_LIST_ITEM_MODIFIER_KEY, DBX_THEME_COLORS, DBX_THEME_COLORS_EXTRA, DBX_THEME_COLORS_EXTRA_SECONDARY, DBX_THEME_COLORS_MAIN, DBX_VALUE_LIST_VIEW_ITEM, DBX_WEB_FILE_PREVIEW_SERVICE_ENTRIES_TOKEN, DBX_WEB_FILE_PREVIEW_SERVICE_ZIP_COMPONENT_PRESET, DBX_WEB_FILE_PREVIEW_SERVICE_ZIP_PRESET_ENTRY, DBX_WEB_PAGE_TITLE_SERVICE_CONFIG, DEFAULT_DBX_CHIP_TONE, DEFAULT_DBX_DETACH_KEY, DEFAULT_DBX_ERROR_SNACKBAR_CONFIG, DEFAULT_DBX_HELP_VIEW_POPOVER_KEY, DEFAULT_DBX_LINKIFY_STRING_TYPE, DEFAULT_DBX_LIST_ACCORDION_VIEW_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_LIST_GRID_VIEW_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_LIST_ITEM_DISABLE_FUNCTION, DEFAULT_DBX_LIST_ITEM_IS_SELECTED_FUNCTION, DEFAULT_DBX_LIST_SCROLL_DISTANCE, DEFAULT_DBX_LIST_THROTTLE_SCROLL, DEFAULT_DBX_LIST_VIEW_META_ICON, DEFAULT_DBX_PROMPT_CONFIRM_DIALOG_CONFIG, DEFAULT_DBX_SELECTION_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_SIDENAV_MENU_ICON, DEFAULT_DBX_STYLE_CONFIG_TOKEN, DEFAULT_DBX_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_DBX_WEB_FILE_PREVIEW_SERVICE_DIALOG_WITH_COMPONENT_FUNCTION, DEFAULT_DBX_WEB_FILE_PREVIEW_SERVICE_PREVIEW_COMPONENT_FUNCTION, DEFAULT_ERROR_POPOVER_KEY, DEFAULT_ERROR_WIDGET_CODE, DEFAULT_FILTER_POPOVER_KEY, DEFAULT_IMAGE_BITMAP_TO_BLOB_ENCODER, DEFAULT_IMAGE_JPEG_QUALITY, DEFAULT_LIST_GRID_SIZE_CONFIG, DEFAULT_LIST_WRAPPER_COMPONENT_CONFIGURATION_TEMPLATE, DEFAULT_LOADING_PROGRESS_DIAMETER, DEFAULT_PDF_MERGE_ACCEPT, DEFAULT_SCREEN_MEDIA_SERVICE_CONFIG, DEFAULT_SNACKBAR_DIRECTIVE_DURATION, DEFAULT_TWO_COLUMNS_MIN_RIGHT_WIDTH, DEFAULT_VALUE_LIST_VIEW_CONTENT_COMPONENT_TRACK_BY_FUNCTION, DbxAccordionHeaderHeightDirective, DbxActionConfirmDirective, DbxActionDialogDirective, DbxActionErrorDirective, DbxActionKeyTriggerDirective, DbxActionLoadingContextDirective, DbxActionModule, DbxActionPopoverDirective, DbxActionSnackbarComponent, DbxActionSnackbarDirective, DbxActionSnackbarErrorDirective, DbxActionSnackbarModule, DbxActionSnackbarService, DbxActionTransitionSafetyDirective, DbxActionUIRouterTransitionSafetyDialogComponent, DbxAnchorComponent, DbxAnchorContentComponent, DbxAnchorIconComponent, DbxAnchorListComponent, DbxAngularRouterSegueAnchorComponent, DbxAvatarComponent, DbxAvatarViewService, DbxAvatarViewServiceConfig, DbxBarDirective, DbxBarHeaderComponent, DbxBarLayoutModule, DbxBasicLoadingComponent, DbxBodyDirective, DbxButtonComponent, DbxButtonModule, DbxButtonSpacerDirective, DbxCardBoxComponent, DbxCardBoxContainerDirective, DbxCardBoxLayoutModule, DbxChipDirective, DbxChipListComponent, DbxClickToCopyTextComponent, DbxClickToCopyTextDirective, DbxColorDirective, DbxColorService, DbxColorServiceConfig, DbxColumnLayoutModule, DbxCompactDirective, DbxCompactLayoutModule, DbxContentBorderDirective, DbxContentBoxDirective, DbxContentContainerDirective, DbxContentDirective, DbxContentElevateDirective, DbxContentLayoutModule, DbxContentPageDirective, DbxContentPitDirective, DbxDetachContentComponent, DbxDetachControlButtonsComponent, DbxDetachController, DbxDetachControlsComponent, DbxDetachInitDirective, DbxDetachInteractionModule, DbxDetachOutletComponent, DbxDetachOverlayComponent, DbxDetachService, DbxDetachWindowState, DbxDetailBlockComponent, DbxDetailBlockHeaderComponent, DbxDialogContentCloseComponent, DbxDialogContentDirective, DbxDialogContentFooterComponent, DbxDialogInteractionModule, DbxDialogModule, DbxDownloadBlobButtonComponent, DbxDownloadTextViewComponent, DbxEmbedComponent, DbxErrorComponent, DbxErrorDefaultErrorWidgetComponent, DbxErrorDetailsComponent, DbxErrorPopoverComponent, DbxErrorSnackbarComponent, DbxErrorSnackbarService, DbxErrorViewComponent, DbxErrorWidgetService, DbxErrorWidgetViewComponent, DbxFileUploadActionCompatable, DbxFileUploadActionSyncDirective, DbxFileUploadAreaComponent, DbxFileUploadButtonComponent, DbxFileUploadComponent, DbxFilterInteractionModule, DbxFilterPopoverButtonComponent, DbxFilterPopoverComponent, DbxFilterWrapperComponent, DbxFlagComponent, DbxFlagLayoutModule, DbxFlagPromptComponent, DbxFlexGroupDirective, DbxFlexLayoutModule, DbxFlexSizeDirective, DbxHelpContextDirective, DbxHelpContextService, DbxHelpViewListComponent, DbxHelpViewListEntryComponent, DbxHelpViewPopoverButtonComponent, DbxHelpViewPopoverComponent, DbxHelpWidgetService, DbxHelpWidgetServiceConfig, DbxIconButtonComponent, DbxIconButtonModule, DbxIconItemComponent, DbxIconSpacerDirective, DbxIconTileComponent, DbxIconTileDirective, DbxIfSidenavDisplayModeDirective, DbxIframeComponent, DbxInjectionDialogComponent, DbxInteractionModule, DbxIntroActionSectionComponent, DbxLabelBlockComponent, DbxLayoutModule, DbxLinkComponent, DbxLinkifyComponent, DbxLinkifyService, DbxLinkifyServiceConfig, DbxListAccordionViewComponentImportsModule, DbxListComponent, DbxListEmptyContentComponent, DbxListGridViewComponentImportsModule, DbxListInternalContentDirective, DbxListItemAnchorModifierDirective, DbxListItemDisableRippleModifierDirective, DbxListItemIsSelectedModifierDirective, DbxListModifierModule, DbxListModule, DbxListTitleGroupDirective, DbxListView, DbxListViewMetaIconComponent, DbxListViewWrapper, DbxListWrapperComponentImportsModule, DbxLoadingComponent, DbxLoadingErrorDirective, DbxLoadingModule, DbxLoadingProgressComponent, DbxModelObjectStateService, actions as DbxModelStateActions, model_actions as DbxModelStateModelActions, DbxModelTrackerService, DbxModelTypesService, DbxModelViewTrackerStorage, DbxNavbarComponent, DbxNumberWithLimitComponent, DbxOneColumnComponent, DbxOneColumnLayoutModule, DbxPagebarComponent, DbxPartialPresetFilterListComponent, DbxPartialPresetFilterMenuComponent, DbxPdfMergeEditorComponent, DbxPdfMergeEditorFileUploadComponent, DbxPdfMergeEditorFileUploadHasStateDirective, DbxPdfMergeEditorFileUploadValidatorDirective, DbxPdfMergeEditorStore, DbxPdfMergeEntryComponent, DbxPdfMergeListComponent, DbxPdfPreviewComponent, DbxPopoverCloseButtonComponent, DbxPopoverComponent, DbxPopoverComponentController, DbxPopoverContentComponent, DbxPopoverController, DbxPopoverControlsDirective, DbxPopoverCoordinatorComponent, DbxPopoverCoordinatorService, DbxPopoverHeaderComponent, DbxPopoverInteractionContentModule, DbxPopoverInteractionModule, DbxPopoverScrollContentDirective, DbxPopoverService, DbxPopupComponent, DbxPopupComponentController, DbxPopupContentComponent, DbxPopupControlButtonsComponent, DbxPopupController, DbxPopupControlsComponent, DbxPopupCoordinatorComponent, DbxPopupCoordinatorService, DbxPopupInteractionModule, DbxPopupService, DbxPopupWindowState, DbxPresetFilterListComponent, DbxPresetFilterMenuComponent, DbxProgressBarButtonComponent, DbxProgressButtonsModule, DbxProgressSpinnerButtonComponent, DbxPromptBoxDirective, DbxPromptComponent, DbxPromptConfirm, DbxPromptConfirmButtonDirective, DbxPromptConfirmComponent, DbxPromptConfirmDialogComponent, DbxPromptConfirmDirective, DbxPromptModule, DbxPromptPageComponent, DbxReadableErrorModule, DbxResizedDirective, DbxRouterAnchorModule, DbxRouterLayoutModule, DbxRouterSidenavModule, DbxRouterWebProviderConfig, DbxScreenMediaService, DbxScreenMediaServiceConfig, DbxSectionComponent, DbxSectionHeaderComponent, DbxSectionLayoutModule, DbxSectionPageComponent, DbxSelectionValueListViewComponent, DbxSelectionValueListViewComponentImportsModule, DbxSelectionValueListViewContentComponent, DbxSetStyleDirective, DbxSidenavButtonComponent, DbxSidenavComponent, DbxSidenavPageComponent, DbxSidenavPagebarComponent, DbxSpacerDirective, DbxStepBlockComponent, DbxStructureDirective, DbxStructureModule, DbxStyleBodyDirective, DbxStyleDirective, DbxStyleLayoutModule, DbxStyleService, DbxSubSectionComponent, DbxTextChipsComponent, DbxTextColorDirective, DbxTextModule, DbxTwoBlockComponent, DbxTwoColumnBackDirective, DbxTwoColumnColumnHeadDirective, DbxTwoColumnComponent, DbxTwoColumnContextDirective, DbxTwoColumnFullLeftDirective, DbxTwoColumnLayoutModule, DbxTwoColumnRightComponent, DbxTwoColumnSrefDirective, DbxTwoColumnSrefShowRightDirective, DbxUIRouterSegueAnchorComponent, DbxUnitedStatesAddressComponent, DbxValueListAccordionViewComponent, DbxValueListAccordionViewContentComponent, DbxValueListAccordionViewContentGroupComponent, DbxValueListGridSizeDirective, DbxValueListGridViewComponent, DbxValueListGridViewContentComponent, DbxValueListGridViewContentGroupComponent, DbxValueListItemModifier, DbxValueListItemModifierDirective, DbxValueListView, DbxValueListViewComponent, DbxValueListViewComponentImportsModule, DbxValueListViewContentComponent, DbxValueListViewContentGroupComponent, DbxValueListViewGroupDelegate, DbxWebFilePreviewComponent, DbxWebFilePreviewService, DbxWebModule, DbxWebPageTitleInfoDirective, DbxWebPageTitleService, DbxWidgetListGridComponent, DbxWidgetListGridViewComponent, DbxWidgetListGridViewItemComponent, DbxWidgetService, DbxWidgetViewComponent, DbxWindowKeyDownListenerDirective, DbxZipBlobPreviewComponent, DbxZipPreviewComponent, PDF_MERGE_RESULT_MIME_TYPE, PopoverPositionStrategy, PopupGlobalPositionStrategy, SCREEN_MEDIA_WIDTH_TYPE_SIZE_MAP, SIDE_NAV_DISPLAY_MODE_ORDER, SideNavDisplayMode, TRACK_BY_MODEL_ID, TRACK_BY_MODEL_KEY, TwoColumnsContextStore, UNKNOWN_ERROR_WIDGET_CODE, addConfigToValueListItems, allDbxModelViewTrackerEventModelKeys, allDbxModelViewTrackerEventSetModelKeys, buildPdfMergeEntry, buildPdfMergeEntrySync, catchErrorServerParams, classifyPdfMergeFile, compactModeFromInput, compareScreenMediaWidthTypes, compressImageFile, convertServerErrorParams, convertToPOJOServerErrorResponse, convertToServerErrorResponse, copyToClipboardFunction, dbxColorBackground, dbxListAccordionViewComponentImportsAndExports, dbxListGridViewComponentImportsAndExports, dbxPresetFilterMenuButtonIconObservable, dbxPresetFilterMenuButtonTextObservable, dbxStyleClassCleanSuffix, dbxThemeColorCssToken, dbxThemeColorCssTokenVar, dbxThemeColorCssVariable, dbxThemeColorCssVariableVar, dbxValueListItemDecisionFunction, dbxValueListItemKeyForItemValue, dbxWebDefaultPageTitleDelegate, dbxZipBlobPreviewEntryTreeFromEntries, defaultDbxModelViewTrackerStorageAccessorFactory, defaultDbxValueListViewGroupDelegate, defaultDbxValueListViewGroupValuesFunction, disableRightClickInCdkBackdrop, fileAcceptFilterTypeStringArray, fileAcceptFunction, fileAcceptString, fileArrayAcceptMatchFunction, flattenAccordionGroups, formatPdfMergeEntrySize, index as fromDbxModel, injectCopyToClipboardFunction, injectCopyToClipboardFunctionWithSnackbarMessage, isDbxColorConfig, listItemModifier, makeDbxActionSnackbarDisplayConfigGeneratorFunction, mapCompactModeObs, mapValuesToValuesListItemConfigObs, mergePdfMergeEntries, index$1 as onDbxModel, openEmbedDialog, openIframeDialog, openPdfPreviewDialog, openZipPreviewDialog, overrideClickElementEffect, provideDbxDetachController, provideDbxFileUploadActionCompatable, provideDbxHelpServices, provideDbxLinkify, provideDbxListView, provideDbxListViewWrapper, provideDbxModelService, provideDbxPdfMergeEditorConfig, provideDbxProgressButtonGlobalConfig, provideDbxPromptConfirm, provideDbxRouterWebAngularRouterProviderConfig, provideDbxRouterWebUiRouterProviderConfig, provideDbxScreenMediaService, provideDbxStyleService, provideDbxValueListView, provideDbxValueListViewGroupDelegate, provideDbxValueListViewModifier, provideDbxWebFilePreviewServiceEntries, provideDbxWebPageTitleService, provideTwoColumnsContext, registerHelpContextKeysWithDbxHelpContextService, resizeSignal, resolveSideNavDisplayMode, sanitizeDbxDialogContentConfig, screenMediaWidthTypeIsActive, trackByModelKeyRef, trackByUniqueIdentifier, validatePdfMergeEntry };
18610
19006
  //# sourceMappingURL=dereekb-dbx-web.mjs.map