@acorex/components 22.3.0 → 22.3.2

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.
@@ -622,10 +622,30 @@ function resolveConversationForViewer(conversation, currentUserId) {
622
622
  icon,
623
623
  };
624
624
  }
625
- /** Whether message reactions are enabled for a conversation. Defaults to `true` when omitted. */
625
+ /**
626
+ * Whether message reactions are enabled for a conversation.
627
+ * `metadata.reactionsEnabled` wins when set; otherwise `bot` chats default to off.
628
+ */
626
629
  function isConversationReactionsEnabled(conversation) {
627
630
  const value = conversation?.metadata?.reactionsEnabled;
628
- return value !== false;
631
+ if (typeof value === 'boolean') {
632
+ return value;
633
+ }
634
+ return conversation?.type !== 'bot';
635
+ }
636
+ /**
637
+ * How file attachments are shown in the composer.
638
+ * `metadata.composerAttachmentPresentation` wins when set; otherwise `bot` chats use `banner`.
639
+ */
640
+ function resolveComposerAttachmentPresentation(conversation) {
641
+ const value = conversation?.metadata?.composerAttachmentPresentation;
642
+ if (value === 'overlay' || value === 'banner') {
643
+ return value;
644
+ }
645
+ return conversation?.type === 'bot' ? 'banner' : 'overlay';
646
+ }
647
+ function isComposerAttachmentBannerEnabled(conversation) {
648
+ return resolveComposerAttachmentPresentation(conversation) === 'banner';
629
649
  }
630
650
 
631
651
  /** Max consecutive emoji graphemes that render as a jumbo (sticker-sized) text message. */
@@ -3335,6 +3355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
3335
3355
  * - Automatic rollback on failures
3336
3356
  */
3337
3357
  class AXConversationService {
3358
+ static { this.createDisplayMetadataKeys = new Set(['title', 'description', 'avatar', 'icon']); }
3338
3359
  static normalizeOptionalString(value) {
3339
3360
  if (typeof value !== 'string') {
3340
3361
  return undefined;
@@ -3342,6 +3363,14 @@ class AXConversationService {
3342
3363
  const normalized = value.trim();
3343
3364
  return normalized.length > 0 ? normalized : undefined;
3344
3365
  }
3366
+ /** Keep flags like `reactionsEnabled`; drop display fields already mapped onto the conversation. */
3367
+ static toPersistedConversationMetadata(metadata) {
3368
+ if (!metadata) {
3369
+ return undefined;
3370
+ }
3371
+ const persisted = Object.fromEntries(Object.entries(metadata).filter(([key]) => !AXConversationService.createDisplayMetadataKeys.has(key)));
3372
+ return Object.keys(persisted).length > 0 ? persisted : undefined;
3373
+ }
3345
3374
  constructor() {
3346
3375
  this.config = inject(AX_CONVERSATION_CONFIG);
3347
3376
  this.state = new AXConversationState(this.config);
@@ -4108,6 +4137,10 @@ class AXConversationService {
4108
4137
  if (!message || !currentUserId) {
4109
4138
  return;
4110
4139
  }
4140
+ const conversation = this.state.getConversation(message.conversationId);
4141
+ if (!isConversationReactionsEnabled(conversation)) {
4142
+ return;
4143
+ }
4111
4144
  const originalReactions = [...message.reactions];
4112
4145
  const hasReaction = message.reactions.some((r) => r.emoji === emoji && r.userId === currentUserId);
4113
4146
  const optimisticReactions = hasReaction
@@ -4723,7 +4756,7 @@ class AXConversationService {
4723
4756
  ? undefined
4724
4757
  : (AXConversationService.normalizeOptionalString(metadata?.['icon']) ??
4725
4758
  (type === 'group' ? AX_CONVERSATION_DEFAULT_GROUP_ICON : undefined)),
4726
- metadata: isPrivate ? undefined : metadata,
4759
+ metadata: AXConversationService.toPersistedConversationMetadata(metadata),
4727
4760
  forceCreate,
4728
4761
  };
4729
4762
  const conversation = await this.callApi('createConversation', 'conversationApi', 'createConversation', () => this.conversationApi.createConversation(createData), createData);
@@ -5399,6 +5432,17 @@ function resolveComposerMaxFiles(action, config) {
5399
5432
  return Math.max(1, action?.maxFiles ?? config.maxFilesPerMessage);
5400
5433
  }
5401
5434
 
5435
+ /** Middle-ellipsis truncation for long file names in picker rows. */
5436
+ function truncatePickerFileName(text, maxLength = 36) {
5437
+ if (text.length <= maxLength) {
5438
+ return text;
5439
+ }
5440
+ const keep = maxLength - 3;
5441
+ const start = Math.ceil(keep / 2);
5442
+ const end = Math.floor(keep / 2);
5443
+ return `${text.slice(0, start)}...${text.slice(text.length - end)}`;
5444
+ }
5445
+
5402
5446
  /** Gradient wash for the default chat wallpaper (pattern tile is applied in component CSS). */
5403
5447
  const MESSAGE_LIST_LIGHT_WALLPAPER_GRADIENT = [
5404
5448
  'radial-gradient(ellipse 85% 70% at 12% 0%, rgba(255, 252, 238, 0.42) 0%, transparent 48%)',
@@ -6517,6 +6561,12 @@ const AX_PASTED_FILE_MIME_BY_EXTENSION = {
6517
6561
  xls: 'application/vnd.ms-excel',
6518
6562
  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
6519
6563
  txt: 'text/plain',
6564
+ js: 'application/octet-stream',
6565
+ mjs: 'application/octet-stream',
6566
+ cjs: 'application/octet-stream',
6567
+ json: 'application/octet-stream',
6568
+ md: 'text/plain',
6569
+ ts: 'text/plain',
6520
6570
  };
6521
6571
  function inferMimeFromFileName(name) {
6522
6572
  const ext = name.split('.').pop()?.trim().toLowerCase() ?? '';
@@ -6534,9 +6584,22 @@ function defaultPastedFileName(type) {
6534
6584
  }
6535
6585
  return 'file';
6536
6586
  }
6587
+ function toCatalogSafeMime(type) {
6588
+ switch (type) {
6589
+ case 'application/javascript':
6590
+ case 'text/javascript':
6591
+ case 'application/json':
6592
+ case 'text/markdown':
6593
+ case 'application/typescript':
6594
+ case 'text/typescript':
6595
+ return 'application/octet-stream';
6596
+ default:
6597
+ return type;
6598
+ }
6599
+ }
6537
6600
  /** Explorer/OS paste often has an empty MIME type; catalogs reject that. */
6538
- function snapshotPastedFile(file) {
6539
- const type = file.type.trim() || inferMimeFromFileName(file.name);
6601
+ function normalizeConversationInboundFile(file) {
6602
+ const type = toCatalogSafeMime(file.type.trim() || inferMimeFromFileName(file.name));
6540
6603
  const name = file.name.trim() || defaultPastedFileName(type);
6541
6604
  if (file.type === type && file.name === name) {
6542
6605
  return file;
@@ -6551,7 +6614,7 @@ function filesFromClipboardEvent(event) {
6551
6614
  if (!file) {
6552
6615
  return;
6553
6616
  }
6554
- const snapshotted = snapshotPastedFile(file);
6617
+ const snapshotted = normalizeConversationInboundFile(file);
6555
6618
  const key = `${snapshotted.name}:${snapshotted.size}:${snapshotted.type}:${snapshotted.lastModified}`;
6556
6619
  if (seen.has(key)) {
6557
6620
  return;
@@ -6884,9 +6947,10 @@ async function promptComposerActionChoice(deps, actions, fileCount) {
6884
6947
  return action;
6885
6948
  }
6886
6949
  /**
6887
- * Match dropped/pasted files to composer picker action(s) and open the popup.
6950
+ * Match dropped/pasted files to composer picker action(s) and open the popup,
6951
+ * or append them to the composer attachment banner when that mode is enabled.
6888
6952
  * Unsupported files are skipped after a warning toast; supported files continue.
6889
- * @returns true when a picker popup was opened
6953
+ * @returns true when a picker popup was opened or files were added to the banner
6890
6954
  */
6891
6955
  async function openComposerPickerForFiles(deps, files) {
6892
6956
  if (!files.length) {
@@ -6896,6 +6960,10 @@ async function openComposerPickerForFiles(deps, files) {
6896
6960
  if (!conversation) {
6897
6961
  return false;
6898
6962
  }
6963
+ if (isComposerAttachmentBannerEnabled(conversation)) {
6964
+ const added = await deps.composerService.addDraftAttachments(files);
6965
+ return added > 0;
6966
+ }
6899
6967
  const analysis = await analyzeInboundFiles(deps, files);
6900
6968
  if (analysis.unsupportedFiles.length > 0) {
6901
6969
  notifyPickerValidationErrors(deps.toast, deps.translation, analysis.unsupportedFiles);
@@ -7124,111 +7192,538 @@ function hasRegistryComponent(ref) {
7124
7192
  return !!ref?.component || !!ref?.componentLoader;
7125
7193
  }
7126
7194
 
7127
- async function openComposerActionOverlay(options) {
7128
- const { popupService, composerService, action, conversation, config, inputs = {}, initialFiles, onClosed } = options;
7129
- const component = action.component ?? (action.componentLoader ? await action.componentLoader() : undefined);
7130
- if (!component) {
7131
- return undefined;
7195
+ function audioItemFromUpload(file, result, duration) {
7196
+ const url = resolvePersistableMediaUrl(result.url);
7197
+ const item = {
7198
+ mediaId: result.mediaId,
7199
+ mimeType: result.mimeType,
7200
+ size: result.size,
7201
+ duration,
7202
+ title: file.name,
7203
+ metadata: result.metadata,
7204
+ };
7205
+ if (url) {
7206
+ item.url = url;
7132
7207
  }
7133
- const hasInitialFiles = !!initialFiles?.length;
7134
- const shouldAutoRun = action.autoRun === true && !hasInitialFiles;
7135
- const contentInputs = {
7136
- conversation,
7137
- maxFiles: resolveComposerMaxFiles(action, config),
7138
- service: composerService,
7139
- autoRun: shouldAutoRun,
7140
- ...inputs,
7208
+ return item;
7209
+ }
7210
+ function mergeAudioUploadResult(payload, result) {
7211
+ const base = normalizeAudioPayload(payload);
7212
+ const audios = [...base.audios];
7213
+ const i = audios.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7214
+ const slot = i >= 0 ? audios[i] : undefined;
7215
+ const url = resolvePersistableMediaUrl(result.url);
7216
+ const next = {
7217
+ ...(slot ?? { duration: 0 }),
7218
+ mediaId: result.mediaId,
7219
+ mimeType: result.mimeType,
7220
+ size: result.size,
7221
+ metadata: result.metadata,
7141
7222
  };
7142
- if (hasInitialFiles) {
7143
- contentInputs['initialFiles'] = initialFiles;
7223
+ if (url) {
7224
+ next.url = url;
7144
7225
  }
7145
- const pickerPanelClass = ['ax-conversation-composer-picker-popup'];
7146
- if (action.id === 'location') {
7147
- pickerPanelClass.push('ax-conversation-composer-picker-popup--location');
7226
+ if (i >= 0)
7227
+ audios[i] = next;
7228
+ else
7229
+ audios.push(next);
7230
+ return { ...base, type: 'audio', audios };
7231
+ }
7232
+ function applyAudioLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
7233
+ const base = normalizeAudioPayload(payload);
7234
+ const audios = [...base.audios];
7235
+ const slot = audios.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7236
+ const preview = { url: localUrl, duration: 0, mimeType };
7237
+ if (slot >= 0) {
7238
+ audios[slot] = { ...audios[slot], ...preview };
7148
7239
  }
7149
- else if (action.id === 'voice-recording') {
7150
- pickerPanelClass.push('ax-conversation-composer-picker-popup--voice');
7240
+ else if (audios.length === 0) {
7241
+ audios.push(preview);
7151
7242
  }
7152
- const popupRef = await popupService.openRef(component, {
7153
- size: 'sm',
7154
- closeButton: false,
7155
- header: false,
7156
- closeOnBackdropClick: false,
7157
- panelClass: pickerPanelClass,
7158
- inputs: contentInputs,
7159
- });
7160
- popupRef.onClose.subscribe(() => onClosed?.());
7161
- return () => popupRef.close();
7243
+ else {
7244
+ audios[0] = { ...audios[0], ...preview };
7245
+ }
7246
+ return { ...base, type: 'audio', audios };
7162
7247
  }
7163
7248
 
7164
- /**
7165
- * AXConversationComposerService
7166
- * Facade/service for Composer to interact with conversation and manage reply/edit state.
7167
- */
7168
- class AXConversationComposerService {
7169
- constructor() {
7170
- this.conversationService = inject(AXConversationService);
7171
- this.generationState = inject(AXConversationComposerGenerationStateService);
7172
- this.translation = inject(AXTranslationService);
7173
- this.popupService = inject(AXPopupService);
7174
- this.config = inject(AX_CONVERSATION_CONFIG);
7175
- this._activeActionOverlay = signal(null, /* @ts-ignore */
7176
- ...(ngDevMode ? [{ debugName: "_activeActionOverlay" }] : /* istanbul ignore next */ []));
7177
- // Reply/Edit state signals (public as readonly)
7178
- this._replyMessage = signal(null, /* @ts-ignore */
7179
- ...(ngDevMode ? [{ debugName: "_replyMessage" }] : /* istanbul ignore next */ []));
7180
- this._editMessage = signal(null, /* @ts-ignore */
7181
- ...(ngDevMode ? [{ debugName: "_editMessage" }] : /* istanbul ignore next */ []));
7182
- this.replyMessage = this._replyMessage.asReadonly();
7183
- this.editMessage = this._editMessage.asReadonly();
7184
- this.activeConversation = this.conversationService.activeConversation;
7185
- this.activeMessages = this.conversationService.activeMessages;
7186
- /** Draft text */
7187
- this.draftText = signal('', /* @ts-ignore */
7188
- ...(ngDevMode ? [{ debugName: "draftText" }] : /* istanbul ignore next */ []));
7189
- /** Attachments */
7190
- this.attachments = signal([], /* @ts-ignore */
7191
- ...(ngDevMode ? [{ debugName: "attachments" }] : /* istanbul ignore next */ []));
7192
- /** Incremented to request focus on the composer text area (handled by AXConversationComposerComponent). */
7193
- this._focusRequest = signal(0, /* @ts-ignore */
7194
- ...(ngDevMode ? [{ debugName: "_focusRequest" }] : /* istanbul ignore next */ []));
7195
- this.focusRequest = this._focusRequest.asReadonly();
7196
- /** Input placeholder */
7197
- this.placeholder = computed(() => {
7198
- const conversation = this.activeConversation();
7199
- if (!conversation)
7200
- return this.translation.translateSync('@acorex:chat.placeholders.select-conversation');
7201
- return this.translation.translateSync('@acorex:chat.placeholders.type-message');
7202
- }, /* @ts-ignore */
7203
- ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
7204
- /** Number of input rows */
7205
- this.inputRows = computed(() => {
7206
- const text = this.draftText();
7207
- const lines = text.split('\n').length;
7208
- return Math.min(Math.max(lines, 1), 12);
7209
- }, /* @ts-ignore */
7210
- ...(ngDevMode ? [{ debugName: "inputRows" }] : /* istanbul ignore next */ []));
7211
- /** Can send message (draft has content; does not include generation state). */
7212
- this.canSend = computed(() => {
7213
- const text = this.draftText().trim();
7214
- const attachments = this.attachments();
7215
- return text.length > 0 || attachments.length > 0;
7216
- }, /* @ts-ignore */
7217
- ...(ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []));
7218
- /** Whether a background generation (e.g. AI response) is in progress. */
7219
- this.isGenerating = this.generationState.isGenerating;
7220
- /** Whether cancel cleanup is in progress (spinner on primary button). */
7221
- this.isStopping = this.generationState.isStopping;
7222
- /** Primary end-button mode for send / cancel / stopping / voice / locked. */
7223
- this.primaryButtonMode = computed(() => {
7224
- if (this.isStopping()) {
7225
- return 'stopping';
7226
- }
7227
- if (this.editMessage() && this.canSend()) {
7228
- return 'send';
7229
- }
7230
- if (this.isGenerating()) {
7231
- return 'cancel';
7249
+ var audioComposer_payload = /*#__PURE__*/Object.freeze({
7250
+ __proto__: null,
7251
+ applyAudioLocalPreview: applyAudioLocalPreview,
7252
+ audioItemFromUpload: audioItemFromUpload,
7253
+ mergeAudioUploadResult: mergeAudioUploadResult
7254
+ });
7255
+
7256
+ function fileItemFromUpload(file, result, extras) {
7257
+ const extension = file.name.includes('.') ? file.name.split('.').pop() : undefined;
7258
+ const url = resolvePersistableMediaUrl(result.url);
7259
+ const duration = extras?.duration != null && Number.isFinite(extras.duration) ? extras.duration : undefined;
7260
+ const item = {
7261
+ mediaId: result.mediaId,
7262
+ mimeType: result.mimeType,
7263
+ size: result.size,
7264
+ name: file.name,
7265
+ thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
7266
+ extension,
7267
+ duration,
7268
+ metadata: result.metadata,
7269
+ };
7270
+ if (url) {
7271
+ item.url = url;
7272
+ }
7273
+ return item;
7274
+ }
7275
+ function mergeFileUploadResult(payload, result) {
7276
+ const base = normalizeFilePayload(payload);
7277
+ const files = [...base.files];
7278
+ const i = files.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7279
+ const slot = i >= 0 ? files[i] : undefined;
7280
+ const name = slot?.name ?? result.metadata?.['fileName'] ?? 'file';
7281
+ const url = resolvePersistableMediaUrl(result.url);
7282
+ const next = {
7283
+ ...(slot ?? { name, mimeType: result.mimeType }),
7284
+ mediaId: result.mediaId,
7285
+ mimeType: result.mimeType,
7286
+ size: result.size,
7287
+ name,
7288
+ thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl ?? slot?.thumbnailUrl, url),
7289
+ metadata: result.metadata,
7290
+ };
7291
+ if (url) {
7292
+ next.url = url;
7293
+ }
7294
+ if (i >= 0)
7295
+ files[i] = next;
7296
+ else
7297
+ files.push(next);
7298
+ return { ...base, type: 'file', files };
7299
+ }
7300
+ function applyFileLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
7301
+ const base = normalizeFilePayload(payload);
7302
+ const files = [...base.files];
7303
+ const slot = files.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7304
+ const preview = { url: localUrl, name: 'upload', mimeType };
7305
+ if (slot >= 0) {
7306
+ files[slot] = { ...files[slot], ...preview };
7307
+ }
7308
+ else if (files.length === 0) {
7309
+ files.push(preview);
7310
+ }
7311
+ else {
7312
+ files[0] = { ...files[0], ...preview };
7313
+ }
7314
+ return { ...base, type: 'file', files };
7315
+ }
7316
+
7317
+ var fileComposer_payload = /*#__PURE__*/Object.freeze({
7318
+ __proto__: null,
7319
+ applyFileLocalPreview: applyFileLocalPreview,
7320
+ fileItemFromUpload: fileItemFromUpload,
7321
+ mergeFileUploadResult: mergeFileUploadResult
7322
+ });
7323
+
7324
+ const EMPTY = { width: 0, height: 0, duration: 0 };
7325
+ async function probeImageDimensions(source) {
7326
+ if (typeof createImageBitmap === 'function' && typeof source !== 'string') {
7327
+ try {
7328
+ const bitmap = await createImageBitmap(source);
7329
+ const size = { width: bitmap.width, height: bitmap.height };
7330
+ bitmap.close();
7331
+ if (size.width > 0 && size.height > 0) {
7332
+ return size;
7333
+ }
7334
+ }
7335
+ catch {
7336
+ // Fall through to HTMLImageElement.
7337
+ }
7338
+ }
7339
+ return new Promise((resolve) => {
7340
+ const img = new Image();
7341
+ let objectUrl = '';
7342
+ const finish = (width, height) => {
7343
+ if (objectUrl) {
7344
+ URL.revokeObjectURL(objectUrl);
7345
+ }
7346
+ resolve({ width, height });
7347
+ };
7348
+ img.onload = () => finish(img.naturalWidth, img.naturalHeight);
7349
+ img.onerror = () => finish(0, 0);
7350
+ if (typeof source === 'string') {
7351
+ img.src = source;
7352
+ return;
7353
+ }
7354
+ objectUrl = URL.createObjectURL(source);
7355
+ img.src = objectUrl;
7356
+ });
7357
+ }
7358
+ async function probeAudioDuration(source) {
7359
+ if (typeof document === 'undefined') {
7360
+ return 0;
7361
+ }
7362
+ return new Promise((resolve) => {
7363
+ const el = document.createElement('audio');
7364
+ el.preload = 'metadata';
7365
+ const objectUrl = URL.createObjectURL(source);
7366
+ const finish = (duration) => {
7367
+ URL.revokeObjectURL(objectUrl);
7368
+ el.src = '';
7369
+ resolve(duration);
7370
+ };
7371
+ el.onloadedmetadata = () => {
7372
+ finish(Number.isFinite(el.duration) ? el.duration : 0);
7373
+ };
7374
+ el.onerror = () => finish(0);
7375
+ el.src = objectUrl;
7376
+ });
7377
+ }
7378
+ async function probeVideoMedia(source) {
7379
+ if (typeof document === 'undefined') {
7380
+ return EMPTY;
7381
+ }
7382
+ return new Promise((resolve) => {
7383
+ const el = document.createElement('video');
7384
+ el.preload = 'metadata';
7385
+ const objectUrl = URL.createObjectURL(source);
7386
+ const finish = (dims) => {
7387
+ URL.revokeObjectURL(objectUrl);
7388
+ el.src = '';
7389
+ resolve(dims);
7390
+ };
7391
+ el.onloadedmetadata = () => {
7392
+ finish({
7393
+ width: el.videoWidth || 0,
7394
+ height: el.videoHeight || 0,
7395
+ duration: Number.isFinite(el.duration) ? el.duration : 0,
7396
+ });
7397
+ };
7398
+ el.onerror = () => finish(EMPTY);
7399
+ el.src = objectUrl;
7400
+ });
7401
+ }
7402
+
7403
+ var mediaDimensions = /*#__PURE__*/Object.freeze({
7404
+ __proto__: null,
7405
+ probeAudioDuration: probeAudioDuration,
7406
+ probeImageDimensions: probeImageDimensions,
7407
+ probeVideoMedia: probeVideoMedia
7408
+ });
7409
+
7410
+ async function imageItemFromUpload(file, result) {
7411
+ const url = resolvePersistableMediaUrl(result.url);
7412
+ const size = await probeImageDimensions(file);
7413
+ const item = {
7414
+ mediaId: result.mediaId,
7415
+ mimeType: result.mimeType,
7416
+ size: result.size,
7417
+ thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
7418
+ width: size.width,
7419
+ height: size.height,
7420
+ metadata: result.metadata,
7421
+ };
7422
+ if (url) {
7423
+ item.url = url;
7424
+ }
7425
+ return item;
7426
+ }
7427
+
7428
+ async function videoItemFromUpload(file, result, duration, size) {
7429
+ const url = resolvePersistableMediaUrl(result.url);
7430
+ const probed = size?.width && size.height
7431
+ ? { width: size.width, height: size.height, duration }
7432
+ : await probeVideoMedia(file);
7433
+ const item = {
7434
+ mediaId: result.mediaId,
7435
+ mimeType: result.mimeType,
7436
+ size: result.size,
7437
+ thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
7438
+ duration: duration || probed.duration,
7439
+ width: probed.width,
7440
+ height: probed.height,
7441
+ metadata: result.metadata,
7442
+ };
7443
+ if (url) {
7444
+ item.url = url;
7445
+ }
7446
+ return item;
7447
+ }
7448
+ function mergeVideoUploadResult(payload, result) {
7449
+ const base = normalizeVideoPayload(payload);
7450
+ const videos = [...base.videos];
7451
+ const i = videos.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7452
+ const slot = i >= 0 ? videos[i] : undefined;
7453
+ const url = resolvePersistableMediaUrl(result.url);
7454
+ const next = {
7455
+ ...(slot ?? { duration: 0, width: 0, height: 0 }),
7456
+ mediaId: result.mediaId,
7457
+ mimeType: result.mimeType,
7458
+ size: result.size,
7459
+ thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl ?? slot?.thumbnailUrl, url),
7460
+ metadata: result.metadata,
7461
+ };
7462
+ if (url) {
7463
+ next.url = url;
7464
+ }
7465
+ if (i >= 0)
7466
+ videos[i] = next;
7467
+ else
7468
+ videos.push(next);
7469
+ return { ...base, type: 'video', videos };
7470
+ }
7471
+ function applyVideoLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
7472
+ const base = normalizeVideoPayload(payload);
7473
+ const videos = [...base.videos];
7474
+ const slot = videos.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
7475
+ const preview = { url: localUrl, duration: 0, width: 0, height: 0, mimeType };
7476
+ if (slot >= 0) {
7477
+ videos[slot] = { ...videos[slot], ...preview };
7478
+ }
7479
+ else if (videos.length === 0) {
7480
+ videos.push(preview);
7481
+ }
7482
+ else {
7483
+ videos[0] = { ...videos[0], ...preview };
7484
+ }
7485
+ return { ...base, type: 'video', videos };
7486
+ }
7487
+
7488
+ var videoComposer_payload = /*#__PURE__*/Object.freeze({
7489
+ __proto__: null,
7490
+ applyVideoLocalPreview: applyVideoLocalPreview,
7491
+ mergeVideoUploadResult: mergeVideoUploadResult,
7492
+ videoItemFromUpload: videoItemFromUpload
7493
+ });
7494
+
7495
+ const DRAFT_KIND_CATALOGS = [
7496
+ { catalog: AX_CONVERSATION_IMAGE_CATALOG, kind: 'image' },
7497
+ { catalog: AX_CONVERSATION_VIDEO_CATALOG, kind: 'video' },
7498
+ { catalog: AX_CONVERSATION_AUDIO_CATALOG, kind: 'audio' },
7499
+ { catalog: AX_CONVERSATION_FILE_CATALOG, kind: 'file' },
7500
+ ];
7501
+ const DRAFT_KIND_ICONS = {
7502
+ image: 'fa-light fa-image',
7503
+ video: 'fa-light fa-video',
7504
+ audio: 'fa-light fa-music',
7505
+ file: 'fa-light fa-file',
7506
+ };
7507
+ function isBannerEligibleComposerAction(action) {
7508
+ return !!action.fileType && action.fileType !== AX_CONVERSATION_VOICE_CATALOG;
7509
+ }
7510
+ function createDraftAttachmentPreviewUrl(file, kind) {
7511
+ if (typeof URL === 'undefined' || typeof URL.createObjectURL !== 'function') {
7512
+ return undefined;
7513
+ }
7514
+ if (kind === 'image' || kind === 'video') {
7515
+ return URL.createObjectURL(file);
7516
+ }
7517
+ return undefined;
7518
+ }
7519
+ function draftAttachmentIcon(kind) {
7520
+ return DRAFT_KIND_ICONS[kind];
7521
+ }
7522
+ function areDraftAttachmentsReady(items) {
7523
+ return items.length > 0 && items.every((item) => isPickerItemReadyToSend(item) && !item.uploading && !item.error);
7524
+ }
7525
+ async function classifyDraftAttachmentKind(fileService, file) {
7526
+ let lastErrors = [];
7527
+ for (const { catalog, kind } of DRAFT_KIND_CATALOGS) {
7528
+ const errors = await fileService.validate(file, catalog);
7529
+ if (errors.length === 0) {
7530
+ return { kind, errors: [] };
7531
+ }
7532
+ lastErrors = errors;
7533
+ }
7534
+ return { kind: 'file', errors: lastErrors };
7535
+ }
7536
+ async function probeDraftAttachmentDuration(file, kind) {
7537
+ if (kind === 'video') {
7538
+ const probed = await probeVideoMedia(file);
7539
+ return probed.duration;
7540
+ }
7541
+ if (kind === 'audio') {
7542
+ return probeAudioDuration(file);
7543
+ }
7544
+ return undefined;
7545
+ }
7546
+ async function buildComposerDraftAttachmentCommand(conversationId, items, caption) {
7547
+ const ready = items.filter((item) => isPickerItemReadyToSend(item));
7548
+ if (ready.length === 0) {
7549
+ return null;
7550
+ }
7551
+ const trimmedCaption = caption?.trim() || undefined;
7552
+ const kinds = new Set(ready.map((item) => item.kind));
7553
+ if (kinds.size === 1 && kinds.has('image')) {
7554
+ const images = (await Promise.all(ready.map(async (item) => {
7555
+ const result = pickerItemToUploadResult(item);
7556
+ return result ? imageItemFromUpload(item.file, result) : null;
7557
+ }))).filter((item) => item !== null);
7558
+ if (images.length === 0) {
7559
+ return null;
7560
+ }
7561
+ return {
7562
+ conversationId,
7563
+ type: 'image',
7564
+ payload: { type: 'image', images, caption: trimmedCaption },
7565
+ };
7566
+ }
7567
+ if (kinds.size === 1 && kinds.has('video')) {
7568
+ const videos = (await Promise.all(ready.map(async (item) => {
7569
+ const result = pickerItemToUploadResult(item);
7570
+ return result ? videoItemFromUpload(item.file, result, item.duration ?? 0) : null;
7571
+ }))).filter((item) => item !== null);
7572
+ if (videos.length === 0) {
7573
+ return null;
7574
+ }
7575
+ return {
7576
+ conversationId,
7577
+ type: 'video',
7578
+ payload: { type: 'video', videos, caption: trimmedCaption },
7579
+ };
7580
+ }
7581
+ if (kinds.size === 1 && kinds.has('audio')) {
7582
+ const audios = ready.flatMap((item) => {
7583
+ const result = pickerItemToUploadResult(item);
7584
+ return result ? [audioItemFromUpload(item.file, result, item.duration ?? 0)] : [];
7585
+ });
7586
+ if (audios.length === 0) {
7587
+ return null;
7588
+ }
7589
+ return {
7590
+ conversationId,
7591
+ type: 'audio',
7592
+ payload: { type: 'audio', audios, caption: trimmedCaption },
7593
+ };
7594
+ }
7595
+ const files = ready.flatMap((item) => {
7596
+ const result = pickerItemToUploadResult(item);
7597
+ return result ? [fileItemFromUpload(item.file, result, { duration: item.duration })] : [];
7598
+ });
7599
+ if (files.length === 0) {
7600
+ return null;
7601
+ }
7602
+ return {
7603
+ conversationId,
7604
+ type: 'file',
7605
+ payload: { type: 'file', files, caption: trimmedCaption },
7606
+ };
7607
+ }
7608
+
7609
+ async function openComposerActionOverlay(options) {
7610
+ const { popupService, composerService, action, conversation, config, inputs = {}, initialFiles, onClosed } = options;
7611
+ const component = action.component ?? (action.componentLoader ? await action.componentLoader() : undefined);
7612
+ if (!component) {
7613
+ return undefined;
7614
+ }
7615
+ const hasInitialFiles = !!initialFiles?.length;
7616
+ const shouldAutoRun = action.autoRun === true && !hasInitialFiles;
7617
+ const contentInputs = {
7618
+ conversation,
7619
+ maxFiles: resolveComposerMaxFiles(action, config),
7620
+ service: composerService,
7621
+ autoRun: shouldAutoRun,
7622
+ ...inputs,
7623
+ };
7624
+ if (hasInitialFiles) {
7625
+ contentInputs['initialFiles'] = initialFiles;
7626
+ }
7627
+ const pickerPanelClass = ['ax-conversation-composer-picker-popup'];
7628
+ if (action.id === 'location') {
7629
+ pickerPanelClass.push('ax-conversation-composer-picker-popup--location');
7630
+ }
7631
+ else if (action.id === 'voice-recording') {
7632
+ pickerPanelClass.push('ax-conversation-composer-picker-popup--voice');
7633
+ }
7634
+ const popupRef = await popupService.openRef(component, {
7635
+ size: 'sm',
7636
+ closeButton: false,
7637
+ header: false,
7638
+ closeOnBackdropClick: false,
7639
+ panelClass: pickerPanelClass,
7640
+ inputs: contentInputs,
7641
+ });
7642
+ popupRef.onClose.subscribe(() => onClosed?.());
7643
+ return () => popupRef.close();
7644
+ }
7645
+
7646
+ /**
7647
+ * AXConversationComposerService
7648
+ * Facade/service for Composer to interact with conversation and manage reply/edit state.
7649
+ */
7650
+ class AXConversationComposerService {
7651
+ constructor() {
7652
+ this.conversationService = inject(AXConversationService);
7653
+ this.generationState = inject(AXConversationComposerGenerationStateService);
7654
+ this.translation = inject(AXTranslationService);
7655
+ this.popupService = inject(AXPopupService);
7656
+ this.uploader = inject(AXUploaderService);
7657
+ this.fileService = inject(AXFileService);
7658
+ this.toast = inject(AXToastService);
7659
+ this.config = inject(AX_CONVERSATION_CONFIG);
7660
+ this.destroyRef = inject(DestroyRef);
7661
+ this._activeActionOverlay = signal(null, /* @ts-ignore */
7662
+ ...(ngDevMode ? [{ debugName: "_activeActionOverlay" }] : /* istanbul ignore next */ []));
7663
+ // Reply/Edit state signals (public as readonly)
7664
+ this._replyMessage = signal(null, /* @ts-ignore */
7665
+ ...(ngDevMode ? [{ debugName: "_replyMessage" }] : /* istanbul ignore next */ []));
7666
+ this._editMessage = signal(null, /* @ts-ignore */
7667
+ ...(ngDevMode ? [{ debugName: "_editMessage" }] : /* istanbul ignore next */ []));
7668
+ this.replyMessage = this._replyMessage.asReadonly();
7669
+ this.editMessage = this._editMessage.asReadonly();
7670
+ this.activeConversation = this.conversationService.activeConversation;
7671
+ this.activeMessages = this.conversationService.activeMessages;
7672
+ /** Draft text */
7673
+ this.draftText = signal('', /* @ts-ignore */
7674
+ ...(ngDevMode ? [{ debugName: "draftText" }] : /* istanbul ignore next */ []));
7675
+ /** Inline composer attachments shown above the input in banner mode. */
7676
+ this.draftAttachments = signal([], /* @ts-ignore */
7677
+ ...(ngDevMode ? [{ debugName: "draftAttachments" }] : /* istanbul ignore next */ []));
7678
+ this.draftAttachmentsReady = computed(() => areDraftAttachmentsReady(this.draftAttachments()), /* @ts-ignore */
7679
+ ...(ngDevMode ? [{ debugName: "draftAttachmentsReady" }] : /* istanbul ignore next */ []));
7680
+ this.usesAttachmentBanner = computed(() => isComposerAttachmentBannerEnabled(this.activeConversation()), /* @ts-ignore */
7681
+ ...(ngDevMode ? [{ debugName: "usesAttachmentBanner" }] : /* istanbul ignore next */ []));
7682
+ /** Incremented to request focus on the composer text area (handled by AXConversationComposerComponent). */
7683
+ this._focusRequest = signal(0, /* @ts-ignore */
7684
+ ...(ngDevMode ? [{ debugName: "_focusRequest" }] : /* istanbul ignore next */ []));
7685
+ this.focusRequest = this._focusRequest.asReadonly();
7686
+ /** Input placeholder */
7687
+ this.placeholder = computed(() => {
7688
+ const conversation = this.activeConversation();
7689
+ if (!conversation)
7690
+ return this.translation.translateSync('@acorex:chat.placeholders.select-conversation');
7691
+ return this.translation.translateSync('@acorex:chat.placeholders.type-message');
7692
+ }, /* @ts-ignore */
7693
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
7694
+ /** Number of input rows */
7695
+ this.inputRows = computed(() => {
7696
+ const text = this.draftText();
7697
+ const lines = text.split('\n').length;
7698
+ return Math.min(Math.max(lines, 1), 12);
7699
+ }, /* @ts-ignore */
7700
+ ...(ngDevMode ? [{ debugName: "inputRows" }] : /* istanbul ignore next */ []));
7701
+ /** Can send message (draft has content; does not include generation state). */
7702
+ this.canSend = computed(() => {
7703
+ const attachments = this.draftAttachments();
7704
+ if (attachments.length > 0) {
7705
+ return this.draftAttachmentsReady();
7706
+ }
7707
+ return this.draftText().trim().length > 0;
7708
+ }, /* @ts-ignore */
7709
+ ...(ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []));
7710
+ /** Whether a background generation (e.g. AI response) is in progress. */
7711
+ this.isGenerating = this.generationState.isGenerating;
7712
+ /** Whether cancel cleanup is in progress (spinner on primary button). */
7713
+ this.isStopping = this.generationState.isStopping;
7714
+ /** Primary end-button mode for send / cancel / stopping / voice / locked. */
7715
+ this.primaryButtonMode = computed(() => {
7716
+ if (this.isStopping()) {
7717
+ return 'stopping';
7718
+ }
7719
+ if (this.editMessage() && this.canSend()) {
7720
+ return 'send';
7721
+ }
7722
+ if (this.isGenerating()) {
7723
+ return 'cancel';
7724
+ }
7725
+ if (this.draftAttachments().length > 0) {
7726
+ return 'send';
7232
7727
  }
7233
7728
  if (this.canSend()) {
7234
7729
  return 'send';
@@ -7306,6 +7801,7 @@ class AXConversationComposerService {
7306
7801
  return this.registry.composerActions.getVisibleActions('end', context).find((action) => action.default);
7307
7802
  }, /* @ts-ignore */
7308
7803
  ...(ngDevMode ? [{ debugName: "defaultAction" }] : /* istanbul ignore next */ []));
7804
+ this.destroyRef.onDestroy(() => this.clearDraftAttachments());
7309
7805
  }
7310
7806
  // Access registry through conversation service
7311
7807
  get registry() {
@@ -7330,6 +7826,7 @@ class AXConversationComposerService {
7330
7826
  }
7331
7827
  clear() {
7332
7828
  this.hideComponent();
7829
+ this.clearDraftAttachments();
7333
7830
  this._replyMessage.set(null);
7334
7831
  this._editMessage.set(null);
7335
7832
  }
@@ -7341,7 +7838,6 @@ class AXConversationComposerService {
7341
7838
  this.saveDraft(previousConversationId, this.draftText());
7342
7839
  }
7343
7840
  this.clear();
7344
- this.attachments.set([]);
7345
7841
  this.draftText.set(currentConversationId ? this.loadDraft(currentConversationId) : '');
7346
7842
  this.generationState.setGenerating(false);
7347
7843
  if (currentConversationId) {
@@ -7362,7 +7858,7 @@ class AXConversationComposerService {
7362
7858
  */
7363
7859
  clearComposerInput(conversationId) {
7364
7860
  this.draftText.set('');
7365
- this.attachments.set([]);
7861
+ this.clearDraftAttachments({ retainUploaded: true });
7366
7862
  this.hideComponent();
7367
7863
  this._replyMessage.set(null);
7368
7864
  this._editMessage.set(null);
@@ -7375,6 +7871,14 @@ class AXConversationComposerService {
7375
7871
  * Open a composer action component in a popup (desktop) or action sheet (mobile).
7376
7872
  */
7377
7873
  async openActionComponent(action, inputs, options) {
7874
+ if (this.usesAttachmentBanner() && isBannerEligibleComposerAction(action)) {
7875
+ if (options?.initialFiles?.length) {
7876
+ await this.addDraftAttachments(options.initialFiles);
7877
+ return;
7878
+ }
7879
+ await this.browseDraftAttachments(action.fileType);
7880
+ return;
7881
+ }
7378
7882
  if (options?.toggleable) {
7379
7883
  const current = this._activeActionOverlay();
7380
7884
  if (current?.actionId === action.id) {
@@ -7408,6 +7912,114 @@ class AXConversationComposerService {
7408
7912
  },
7409
7913
  });
7410
7914
  }
7915
+ async browseDraftAttachments(fileType) {
7916
+ const { accepted, rejected } = await this.uploader.chooseFiles({
7917
+ multiple: true,
7918
+ fileType,
7919
+ });
7920
+ notifyPickerValidationErrors(this.toast, this.translation, rejected);
7921
+ if (!accepted.length) {
7922
+ return 0;
7923
+ }
7924
+ return this.addDraftAttachments(accepted);
7925
+ }
7926
+ async addDraftAttachments(files) {
7927
+ const conversation = this.activeConversation();
7928
+ if (!conversation || files.length === 0) {
7929
+ return 0;
7930
+ }
7931
+ const max = Math.max(1, this.config.maxFilesPerMessage);
7932
+ const incoming = files.map((file) => normalizeConversationInboundFile(file));
7933
+ const capacity = limitFilesToCapacity(incoming, this.draftAttachments().length, max);
7934
+ if (capacity.length < incoming.length) {
7935
+ notifyMaxFilesCapacityExceeded(this.toast, this.translation, max);
7936
+ }
7937
+ if (capacity.length === 0) {
7938
+ return 0;
7939
+ }
7940
+ const accepted = [];
7941
+ const rejected = [];
7942
+ for (const file of capacity) {
7943
+ const classified = await classifyDraftAttachmentKind(this.fileService, file);
7944
+ if (classified.errors.length > 0) {
7945
+ rejected.push({ file, errors: classified.errors });
7946
+ continue;
7947
+ }
7948
+ const id = createPickerUploadItemId();
7949
+ const preview = createDraftAttachmentPreviewUrl(file, classified.kind);
7950
+ const duration = await probeDraftAttachmentDuration(file, classified.kind);
7951
+ const item = {
7952
+ id,
7953
+ file,
7954
+ kind: classified.kind,
7955
+ icon: draftAttachmentIcon(classified.kind),
7956
+ preview,
7957
+ duration,
7958
+ uploadProgress: 0,
7959
+ uploading: true,
7960
+ };
7961
+ this.draftAttachments.update((current) => [...current, item]);
7962
+ accepted.push(file);
7963
+ void this.uploadDraftAttachment(id, conversation.id, file);
7964
+ }
7965
+ notifyPickerValidationErrors(this.toast, this.translation, rejected);
7966
+ return accepted.length;
7967
+ }
7968
+ removeDraftAttachment(id) {
7969
+ const item = this.draftAttachments().find((attachment) => attachment.id === id);
7970
+ if (!item) {
7971
+ return;
7972
+ }
7973
+ cleanupPickerUploads(this.uploader, [item]);
7974
+ this.draftAttachments.update((items) => items.filter((attachment) => attachment.id !== id));
7975
+ }
7976
+ clearDraftAttachments(options) {
7977
+ const snapshot = this.draftAttachments();
7978
+ if (snapshot.length === 0) {
7979
+ return;
7980
+ }
7981
+ cleanupPickerUploads(this.uploader, snapshot, { retainUploaded: options?.retainUploaded });
7982
+ this.draftAttachments.set([]);
7983
+ }
7984
+ async buildDraftAttachmentCommand(caption) {
7985
+ const conversation = this.activeConversation();
7986
+ if (!conversation) {
7987
+ return null;
7988
+ }
7989
+ return buildComposerDraftAttachmentCommand(conversation.id, this.draftAttachments(), caption);
7990
+ }
7991
+ async uploadDraftAttachment(id, conversationId, file) {
7992
+ const abortController = new AbortController();
7993
+ this.patchDraftAttachment(id, { abortController });
7994
+ try {
7995
+ const result = await uploadPickerFile(this.uploader, conversationId, file, (progress) => {
7996
+ this.patchDraftAttachment(id, { uploadProgress: progress, uploading: true });
7997
+ }, abortController.signal);
7998
+ this.patchDraftAttachment(id, {
7999
+ uploadProgress: 100,
8000
+ uploading: false,
8001
+ uploaded: true,
8002
+ uploadedUrl: result.url,
8003
+ mediaId: result.mediaId,
8004
+ error: undefined,
8005
+ });
8006
+ }
8007
+ catch (error) {
8008
+ if (isUploadAborted(error, abortController.signal)) {
8009
+ return;
8010
+ }
8011
+ console.error('Failed to upload composer attachment:', error);
8012
+ this.patchDraftAttachment(id, {
8013
+ uploadProgress: 0,
8014
+ uploading: false,
8015
+ uploaded: false,
8016
+ error: this.translation.translateSync('@acorex:chat.errors.upload-failed'),
8017
+ });
8018
+ }
8019
+ }
8020
+ patchDraftAttachment(id, patch) {
8021
+ this.draftAttachments.update((items) => items.map((item) => (item.id === id ? { ...item, ...patch } : item)));
8022
+ }
7411
8023
  /**
7412
8024
  * Hide the active action overlay.
7413
8025
  */
@@ -7476,7 +8088,7 @@ class AXConversationComposerService {
7476
8088
  }
7477
8089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationComposerService, decorators: [{
7478
8090
  type: Injectable
7479
- }] });
8091
+ }], ctorParameters: () => [] });
7480
8092
 
7481
8093
  /**
7482
8094
  * Composer Component
@@ -7504,8 +8116,9 @@ class AXConversationComposerComponent {
7504
8116
  this.textAreaRef = viewChild('inputElement', { ...(ngDevMode ? { debugName: "textAreaRef" } : /* istanbul ignore next */ {}), read: AXTextAreaComponent });
7505
8117
  /** Draft text - use service */
7506
8118
  this.draftText = this.composerService.draftText;
7507
- /** Attachments - use service */
7508
- this.attachments = this.composerService.attachments;
8119
+ /** Draft attachments shown above the composer in banner mode. */
8120
+ this.draftAttachments = this.composerService.draftAttachments;
8121
+ this.usesAttachmentBanner = this.composerService.usesAttachmentBanner;
7509
8122
  /** Editing message */
7510
8123
  this.editingMessage = signal(null, /* @ts-ignore */
7511
8124
  ...(ngDevMode ? [{ debugName: "editingMessage" }] : /* istanbul ignore next */ []));
@@ -7692,7 +8305,7 @@ class AXConversationComposerComponent {
7692
8305
  try {
7693
8306
  await this.conversationService.editMessage(editingMsg.id, { type: 'text', text });
7694
8307
  this.draftText.set('');
7695
- this.attachments.set([]);
8308
+ this.composerService.clearDraftAttachments();
7696
8309
  this.cancelEditReply();
7697
8310
  this.composerService.clearDraft(conversation.id);
7698
8311
  this.messageListService.requestScrollToBottom();
@@ -7703,6 +8316,29 @@ class AXConversationComposerComponent {
7703
8316
  }
7704
8317
  return;
7705
8318
  }
8319
+ const draftAttachments = this.draftAttachments();
8320
+ if (draftAttachments.length > 0) {
8321
+ if (!this.composerService.draftAttachmentsReady()) {
8322
+ return;
8323
+ }
8324
+ const command = await this.composerService.buildDraftAttachmentCommand(text || undefined);
8325
+ if (!command) {
8326
+ return;
8327
+ }
8328
+ this.editingMessage.set(null);
8329
+ this.replyingToMessage.set(null);
8330
+ this.conversationService.notifyComposerStoppedTyping(conversation.id);
8331
+ this.messageListService.requestScrollToBottom();
8332
+ void this.composerService
8333
+ .sendMessage(command)
8334
+ .then(() => {
8335
+ this.messageSent.emit(command);
8336
+ })
8337
+ .catch((error) => {
8338
+ console.error('Failed to send message:', error);
8339
+ });
8340
+ return;
8341
+ }
7706
8342
  const command = {
7707
8343
  conversationId: conversation.id,
7708
8344
  type: 'text',
@@ -7950,6 +8586,9 @@ class AXConversationComposerComponent {
7950
8586
  if (mode === 'locked' || mode === 'stopping') {
7951
8587
  return true;
7952
8588
  }
8589
+ if (mode === 'send') {
8590
+ return !this.canSend();
8591
+ }
7953
8592
  if (mode === 'default-action') {
7954
8593
  const action = this.defaultAction();
7955
8594
  return action ? !this.isActionEnabled(action) : true;
@@ -7964,9 +8603,18 @@ class AXConversationComposerComponent {
7964
8603
  onVoiceClick() {
7965
8604
  this.voiceClick.emit();
7966
8605
  }
7967
- /** Remove attachment */
7968
- removeAttachment(index) {
7969
- this.attachments.update((files) => files.filter((_, i) => i !== index));
8606
+ /** Remove a draft attachment from the composer banner. */
8607
+ removeDraftAttachment(id) {
8608
+ this.composerService.removeDraftAttachment(id);
8609
+ }
8610
+ addDraftAttachments() {
8611
+ void this.composerService.browseDraftAttachments();
8612
+ }
8613
+ draftAttachmentLabel(name) {
8614
+ return truncatePickerFileName(name, 18);
8615
+ }
8616
+ canAddDraftAttachments() {
8617
+ return this.draftAttachments().length < Math.max(1, this.config.maxFilesPerMessage);
7970
8618
  }
7971
8619
  /** Cancel edit/reply mode */
7972
8620
  cancelEditReply() {
@@ -8151,7 +8799,7 @@ class AXConversationComposerComponent {
8151
8799
  };
8152
8800
  }
8153
8801
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationComposerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8154
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXConversationComposerComponent, isStandalone: true, selector: "ax-conversation-composer", outputs: { messageSent: "messageSent", generationCancelled: "generationCancelled", emojiClick: "emojiClick", attachClick: "attachClick", voiceClick: "voiceClick" }, host: { listeners: { "paste": "onComposerPaste($event)" } }, viewQueries: [{ propertyName: "textAreaRef", first: true, predicate: ["inputElement"], descendants: true, read: AXTextAreaComponent, isSignal: true }, { propertyName: "emojiPopoverRef", first: true, predicate: ["emojiPopover"], descendants: true, isSignal: true }, { propertyName: "attachPopoverRef", first: true, predicate: ["attachPopover"], descendants: true, isSignal: true }, { propertyName: "attachMenuButtonRef", first: true, predicate: ["attachMenuButton"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (activeConversation()) {\n <div class=\"composer\">\n <!-- Edit/Reply Banner -->\n @if (editingMessage() || replyingToMessage()) {\n <div\n class=\"ax-conversation-composer-banner\"\n [class.ax-conversation-composer-banner--edit]=\"!!editingMessage()\"\n [class.ax-conversation-composer-banner--reply]=\"!!replyingToMessage()\"\n >\n <div class=\"ax-conversation-composer-banner__accent\" aria-hidden=\"true\"></div>\n @if (editingMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-pen-to-square\"></i\n ></span>\n <div class=\"ax-conversation-composer-banner__body\">\n <span class=\"ax-conversation-composer-banner__label\">{{\n '@acorex:chat.composer.editing-message' | translate | async\n }}</span>\n @if (getEditingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n } @else if (replyingToMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-reply\"></i\n ></span>\n <div\n class=\"ax-conversation-composer-banner__body ax-conversation-composer-banner__body--clickable\"\n (click)=\"onReplyPreviewClick()\"\n >\n <span class=\"ax-conversation-composer-banner__label\">\n {{ '@acorex:chat.composer.replying-to' | translate | async }} {{ getReplyingSenderName() }}\n </span>\n @if (getReplyingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n }\n <ax-button\n class=\"ax-conversation-composer-banner__close rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.cancel')\"\n (onClick)=\"cancelEditReply()\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n\n <!-- Input Area -->\n <div class=\"composer-input-container\">\n <!-- Start actions -->\n <div class=\"composer-actions-left\">\n @if (startMenuActions().length > 0) {\n <span\n #attachMenuButton\n class=\"composer-attach-menu-trigger\"\n (mouseenter)=\"onAttachMenuMouseEnter()\"\n (mouseleave)=\"onAttachMenuMouseLeave()\"\n >\n <ax-button\n class=\"rounded-full text-xl\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"('@acorex:chat.tooltips.attach-file' | translate | async) ?? ''\"\n (onClick)=\"onAttachMenuClick($event)\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-paperclip\"></i>\n </ax-prefix>\n </ax-button>\n </span>\n }\n\n @for (action of startInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <!-- Text Input -->\n <div class=\"composer-input-wrapper\">\n <ax-text-area\n #inputElement\n [ngModel]=\"draftText()\"\n (ngModelChange)=\"onDraftModelChange($event)\"\n (onKeyDown)=\"onKeyDown($event)\"\n (onValueChanged)=\"onDraftValueChanged($event)\"\n [placeholder]=\"placeholder()\"\n [rows]=\"inputRows()\"\n [axAutoFocus]=\"true\"\n ></ax-text-area>\n </div>\n\n <!-- End actions -->\n <div class=\"composer-actions-right\">\n @for (action of endInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n\n <div class=\"composer-primary-button-slot\">\n @switch (primaryButtonMode()) {\n @case ('cancel') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-icon [class]=\"getPrimaryButtonIcon()\"> </ax-icon>\n </ax-button>\n }\n @case ('stopping') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"true\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @case ('send') {\n <ax-button\n class=\"rounded-full composer-primary-button--send\"\n [iconOnly]=\"true\"\n look=\"blank\"\n color=\"primary\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @default {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Attachments Preview -->\n @if (attachments().length > 0) {\n <div class=\"composer-attachments\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item\">\n <span class=\"attachment-icon\"><i class=\"fa-light fa-paperclip\"></i></span>\n <span class=\"attachment-name\">{{ attachment.name }}</span>\n <ax-button\n class=\"attachment-remove rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.remove-attachment')\"\n (onClick)=\"removeAttachment($index)\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- Popover for attachment menu -->\n@if (attachMenuTarget()) {\n <ax-popover\n #attachPopover\n [target]=\"attachMenuTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n >\n <div\n class=\"composer-attach-menu-panel\"\n (mouseenter)=\"onAttachMenuPanelMouseEnter()\"\n (mouseleave)=\"onAttachMenuPanelMouseLeave()\"\n >\n <ax-button-item-list>\n @for (action of startMenuActions(); track action.id) {\n <ax-button-item\n [text]=\"getActionLabel(action)\"\n (click)=\"onAttachMenuAction(action.id)\"\n [disabled]=\"!isActionEnabled(action)\"\n >\n <ax-prefix>\n <i [class]=\"action.icon\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </div>\n </ax-popover>\n}\n\n<!-- Popover for emoji/sticker picker -->\n@if (emojiPopoverTarget()) {\n <ax-popover\n #emojiPopover\n [target]=\"emojiPopoverTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n panelClass=\"composer-emoji-popover-panel\"\n (onClosed)=\"onEmojiPopoverClosed()\"\n >\n <div class=\"composer-emoji-popover\">\n <ax-conversation-registry-component-outlet\n [componentLoader]=\"composerPopupLoader\"\n [inputs]=\"getEmojiPopupInputs()\"\n />\n </div>\n </ax-popover>\n}\n", styles: ["@layer properties;@layer components{ax-conversation-composer{display:block;width:100%;font-variant-emoji:emoji;@keyframes ax-conversation-composer-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}}ax-conversation-composer .ax-conversation-composer-banner{display:flex;min-height:2.75rem;align-items:stretch;gap:calc(var(--spacing, .25rem) * 0);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface))}ax-conversation-composer .ax-conversation-composer-banner__accent{width:3px;flex-shrink:0;border-start-end-radius:var(--radius-sm, .25rem);border-end-end-radius:var(--radius-sm, .25rem);background-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__accent{background-color:rgba(var(--ax-sys-color-secondary-500))}ax-conversation-composer .ax-conversation-composer-banner__content{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-banner__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);font-size:.8125rem;color:rgba(var(--ax-sys-color-primary-600));background:rgba(var(--ax-sys-color-primary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__icon{color:rgba(var(--ax-sys-color-secondary-600));background:rgba(var(--ax-sys-color-secondary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner__body{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}ax-conversation-composer .ax-conversation-composer-banner__body--clickable{cursor:pointer;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__body--clickable:hover{opacity:.85}}ax-conversation-composer .ax-conversation-composer-banner__label{font-size:.6875rem;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:rgba(var(--ax-sys-color-primary-600));text-transform:uppercase}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__label{color:rgba(var(--ax-sys-color-secondary-600))}ax-conversation-composer .ax-conversation-composer-banner__preview{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);overflow:hidden;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface));opacity:.88}ax-conversation-composer .ax-conversation-composer-banner__preview i{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:70%}ax-conversation-composer .ax-conversation-composer-banner__close{margin-inline-end:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;align-self:center}ax-conversation-composer .ax-conversation-composer-banner__close>button{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);cursor:pointer;touch-action:manipulation;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-primary-lightest-surface),.55);box-shadow:none;background-image:none;transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__close:hover>button{color:rgba(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-banner__close>button:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .emoji-icon{flex-shrink:0;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}ax-conversation-composer .composer-input-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1)}ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-icon i,:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-prefix i{font-size:1.375rem;--tw-leading: 1;line-height:1}ax-conversation-composer .composer-attach-menu-trigger{display:inline-flex}ax-conversation-composer .composer-primary-button-slot{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);flex-shrink:0;align-items:center;justify-content:center}ax-conversation-composer .composer-primary-button-slot .composer-primary-button ax-prefix i{transition:opacity .15s ease}ax-conversation-composer .composer-primary-button-slot .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}@media(hover:hover){ax-conversation-composer .composer-actions-left ax-button>button:hover:not(:disabled),ax-conversation-composer .composer-actions-right ax-button:not(.composer-primary-button--send)>button:hover:not(:disabled){color:rgba(var(--ax-sys-color-on-surface),.68);background:rgba(var(--ax-sys-color-on-surface),.05)}}ax-conversation-composer .composer-input-wrapper{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;--tw-border-style: none;border-style:none;--tw-outline-style: none;outline-style:none}ax-conversation-composer .composer-input-wrapper textarea{resize:none;font-variant-emoji:emoji}ax-conversation-composer .composer-input-wrapper .ax-editor-container{--tw-border-style: none;border-style:none;background-color:transparent!important;padding:calc(var(--spacing, .25rem) * 0);--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container ax-text-area{line-height:2}ax-conversation-composer .composer-input-wrapper .ax-editor-container:after{display:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container:hover:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error),ax-conversation-composer .composer-input-wrapper .ax-editor-container:focus-within:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error){--tw-border-style: none;border-style:none;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input{max-height:120px;min-height:calc(var(--spacing, .25rem) * 10);width:100%;resize:none;border-radius:1.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.9375rem;--tw-leading: var(--leading-normal, 1.5);line-height:var(--leading-normal, 1.5);--tw-outline-style: none;outline-style:none;font-variant-emoji:emoji;transition:border-color .2s}ax-conversation-composer .composer-input:focus{border-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .composer-attachments{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);padding-bottom:calc(var(--spacing, .25rem) * 4)}ax-conversation-composer .attachment-item{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);background-color:rgba(var(--ax-sys-color-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}ax-conversation-composer .attachment-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}ax-conversation-composer .attachment-name{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-composer .attachment-remove,ax-conversation-composer .attachment-remove>button{display:flex;height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 5);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));box-shadow:none;background-image:none;transition:background .2s}@media(hover:hover){ax-conversation-composer .attachment-remove:hover>button,ax-conversation-composer .attachment-remove>button:hover{background-color:rgba(var(--ax-sys-color-danger-lightest-surface));color:rgba(var(--ax-sys-color-danger-500))}}ax-conversation-composer .composer-component-fullwidth{min-height:72px;width:100%;background-color:rgba(var(--ax-sys-color-lightest-surface))}ax-conversation-composer .composer-emoji-popover{width:100%}ax-conversation-composer .ax-conversation-composer-primary--stopping .fa-spinner{animation:ax-conversation-composer-spin .75s linear infinite}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-tracking: initial;--tw-leading: initial;--tw-outline-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXConversationRegistryComponentOutletComponent, selector: "ax-conversation-registry-component-outlet", inputs: ["component", "componentLoader", "inputs", "skeleton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXCommonModule }, { kind: "directive", type: i2.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
8802
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXConversationComposerComponent, isStandalone: true, selector: "ax-conversation-composer", outputs: { messageSent: "messageSent", generationCancelled: "generationCancelled", emojiClick: "emojiClick", attachClick: "attachClick", voiceClick: "voiceClick" }, host: { listeners: { "paste": "onComposerPaste($event)" } }, viewQueries: [{ propertyName: "textAreaRef", first: true, predicate: ["inputElement"], descendants: true, read: AXTextAreaComponent, isSignal: true }, { propertyName: "emojiPopoverRef", first: true, predicate: ["emojiPopover"], descendants: true, isSignal: true }, { propertyName: "attachPopoverRef", first: true, predicate: ["attachPopover"], descendants: true, isSignal: true }, { propertyName: "attachMenuButtonRef", first: true, predicate: ["attachMenuButton"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (activeConversation()) {\n <div class=\"composer\">\n <!-- Edit/Reply Banner -->\n @if (editingMessage() || replyingToMessage()) {\n <div\n class=\"ax-conversation-composer-banner\"\n [class.ax-conversation-composer-banner--edit]=\"!!editingMessage()\"\n [class.ax-conversation-composer-banner--reply]=\"!!replyingToMessage()\"\n >\n <div class=\"ax-conversation-composer-banner__accent\" aria-hidden=\"true\"></div>\n @if (editingMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-pen-to-square\"></i\n ></span>\n <div class=\"ax-conversation-composer-banner__body\">\n <span class=\"ax-conversation-composer-banner__label\">{{\n '@acorex:chat.composer.editing-message' | translate | async\n }}</span>\n @if (getEditingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n } @else if (replyingToMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-reply\"></i\n ></span>\n <div\n class=\"ax-conversation-composer-banner__body ax-conversation-composer-banner__body--clickable\"\n (click)=\"onReplyPreviewClick()\"\n >\n <span class=\"ax-conversation-composer-banner__label\">\n {{ '@acorex:chat.composer.replying-to' | translate | async }} {{ getReplyingSenderName() }}\n </span>\n @if (getReplyingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n }\n <ax-button\n class=\"ax-conversation-composer-banner__close rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.cancel')\"\n (onClick)=\"cancelEditReply()\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n\n @if (usesAttachmentBanner() && draftAttachments().length > 0) {\n <div class=\"ax-conversation-composer-attachments\" role=\"list\">\n @for (attachment of draftAttachments(); track attachment.id) {\n <div\n class=\"ax-conversation-composer-attachment\"\n role=\"listitem\"\n [class.ax-conversation-composer-attachment--media]=\"attachment.kind === 'image' || attachment.kind === 'video'\"\n [class.ax-conversation-composer-attachment--file]=\"attachment.kind === 'audio' || attachment.kind === 'file'\"\n [class.ax-conversation-composer-attachment--uploading]=\"attachment.uploading\"\n [class.ax-conversation-composer-attachment--error]=\"!!attachment.error\"\n [title]=\"attachment.file.name\"\n >\n @if (attachment.kind === 'image' || attachment.kind === 'video') {\n <span class=\"ax-conversation-composer-attachment__thumb\" aria-hidden=\"true\">\n @if (attachment.kind === 'video' && attachment.preview) {\n <video [src]=\"attachment.preview\" muted playsinline preload=\"metadata\"></video>\n } @else if (attachment.preview) {\n <img [src]=\"attachment.preview\" alt=\"\" />\n } @else {\n <i [class]=\"attachment.icon\"></i>\n }\n </span>\n } @else {\n <span class=\"ax-conversation-composer-attachment__icon\" aria-hidden=\"true\">\n <i [class]=\"attachment.icon\"></i>\n </span>\n <span class=\"ax-conversation-composer-attachment__name\">{{\n draftAttachmentLabel(attachment.file.name)\n }}</span>\n }\n @if (attachment.uploading) {\n <span class=\"ax-conversation-composer-attachment__progress\" aria-hidden=\"true\"></span>\n }\n <button\n type=\"button\"\n class=\"ax-conversation-composer-attachment__remove\"\n [attr.aria-label]=\"translation.translateSync('@acorex:chat.actions.remove-attachment')\"\n (click)=\"removeDraftAttachment(attachment.id); $event.stopPropagation()\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <button\n type=\"button\"\n class=\"ax-conversation-composer-attachment-add\"\n [disabled]=\"!canAddDraftAttachments()\"\n [attr.aria-label]=\"translation.translateSync('@acorex:chat.pickers.common.add-more')\"\n (click)=\"addDraftAttachments()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </button>\n </div>\n }\n\n <!-- Input Area -->\n <div class=\"composer-input-container\">\n <!-- Start actions -->\n <div class=\"composer-actions-left\">\n @if (startMenuActions().length > 0) {\n <span\n #attachMenuButton\n class=\"composer-attach-menu-trigger\"\n (mouseenter)=\"onAttachMenuMouseEnter()\"\n (mouseleave)=\"onAttachMenuMouseLeave()\"\n >\n <ax-button\n class=\"rounded-full text-xl\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"('@acorex:chat.tooltips.attach-file' | translate | async) ?? ''\"\n (onClick)=\"onAttachMenuClick($event)\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-paperclip\"></i>\n </ax-prefix>\n </ax-button>\n </span>\n }\n\n @for (action of startInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <!-- Text Input -->\n <div class=\"composer-input-wrapper\">\n <ax-text-area\n #inputElement\n [ngModel]=\"draftText()\"\n (ngModelChange)=\"onDraftModelChange($event)\"\n (onKeyDown)=\"onKeyDown($event)\"\n (onValueChanged)=\"onDraftValueChanged($event)\"\n [placeholder]=\"placeholder()\"\n [rows]=\"inputRows()\"\n [axAutoFocus]=\"true\"\n ></ax-text-area>\n </div>\n\n <!-- End actions -->\n <div class=\"composer-actions-right\">\n @for (action of endInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n\n <div class=\"composer-primary-button-slot\">\n @switch (primaryButtonMode()) {\n @case ('cancel') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-icon [class]=\"getPrimaryButtonIcon()\"> </ax-icon>\n </ax-button>\n }\n @case ('stopping') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"true\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @case ('send') {\n <ax-button\n class=\"rounded-full composer-primary-button--send\"\n [iconOnly]=\"true\"\n look=\"blank\"\n color=\"primary\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @default {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n </div>\n </div>\n </div>\n </div>\n}\n\n<!-- Popover for attachment menu -->\n@if (attachMenuTarget()) {\n <ax-popover\n #attachPopover\n [target]=\"attachMenuTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n >\n <div\n class=\"composer-attach-menu-panel\"\n (mouseenter)=\"onAttachMenuPanelMouseEnter()\"\n (mouseleave)=\"onAttachMenuPanelMouseLeave()\"\n >\n <ax-button-item-list>\n @for (action of startMenuActions(); track action.id) {\n <ax-button-item\n [text]=\"getActionLabel(action)\"\n (click)=\"onAttachMenuAction(action.id)\"\n [disabled]=\"!isActionEnabled(action)\"\n >\n <ax-prefix>\n <i [class]=\"action.icon\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </div>\n </ax-popover>\n}\n\n<!-- Popover for emoji/sticker picker -->\n@if (emojiPopoverTarget()) {\n <ax-popover\n #emojiPopover\n [target]=\"emojiPopoverTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n panelClass=\"composer-emoji-popover-panel\"\n (onClosed)=\"onEmojiPopoverClosed()\"\n >\n <div class=\"composer-emoji-popover\">\n <ax-conversation-registry-component-outlet\n [componentLoader]=\"composerPopupLoader\"\n [inputs]=\"getEmojiPopupInputs()\"\n />\n </div>\n </ax-popover>\n}\n", styles: ["@layer properties;@layer components{ax-conversation-composer{display:block;width:100%;font-variant-emoji:emoji;@keyframes ax-conversation-composer-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}}ax-conversation-composer .ax-conversation-composer-banner{display:flex;min-height:2.75rem;align-items:stretch;gap:calc(var(--spacing, .25rem) * 0);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface))}ax-conversation-composer .ax-conversation-composer-banner__accent{width:3px;flex-shrink:0;border-start-end-radius:var(--radius-sm, .25rem);border-end-end-radius:var(--radius-sm, .25rem);background-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__accent{background-color:rgba(var(--ax-sys-color-secondary-500))}ax-conversation-composer .ax-conversation-composer-banner__content{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-banner__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);font-size:.8125rem;color:rgba(var(--ax-sys-color-primary-600));background:rgba(var(--ax-sys-color-primary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__icon{color:rgba(var(--ax-sys-color-secondary-600));background:rgba(var(--ax-sys-color-secondary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner__body{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}ax-conversation-composer .ax-conversation-composer-banner__body--clickable{cursor:pointer;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__body--clickable:hover{opacity:.85}}ax-conversation-composer .ax-conversation-composer-banner__label{font-size:.6875rem;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:rgba(var(--ax-sys-color-primary-600));text-transform:uppercase}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__label{color:rgba(var(--ax-sys-color-secondary-600))}ax-conversation-composer .ax-conversation-composer-banner__preview{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);overflow:hidden;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface));opacity:.88}ax-conversation-composer .ax-conversation-composer-banner__preview i{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:70%}ax-conversation-composer .ax-conversation-composer-banner__close{margin-inline-end:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;align-self:center}ax-conversation-composer .ax-conversation-composer-banner__close>button{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);cursor:pointer;touch-action:manipulation;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-primary-lightest-surface),.55);box-shadow:none;background-image:none;transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__close:hover>button{color:rgba(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-banner__close>button:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .emoji-icon{flex-shrink:0;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}ax-conversation-composer .composer-input-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1)}ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-icon i,:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-prefix i{font-size:1.375rem;--tw-leading: 1;line-height:1}ax-conversation-composer .composer-attach-menu-trigger{display:inline-flex}ax-conversation-composer .composer-primary-button-slot{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);flex-shrink:0;align-items:center;justify-content:center}ax-conversation-composer .composer-primary-button-slot .composer-primary-button ax-prefix i{transition:opacity .15s ease}ax-conversation-composer .composer-primary-button-slot .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}@media(hover:hover){ax-conversation-composer .composer-actions-left ax-button>button:hover:not(:disabled),ax-conversation-composer .composer-actions-right ax-button:not(.composer-primary-button--send)>button:hover:not(:disabled){color:rgba(var(--ax-sys-color-on-surface),.68);background:rgba(var(--ax-sys-color-on-surface),.05)}}ax-conversation-composer .composer-input-wrapper{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;--tw-border-style: none;border-style:none;--tw-outline-style: none;outline-style:none}ax-conversation-composer .composer-input-wrapper textarea{resize:none;font-variant-emoji:emoji}ax-conversation-composer .composer-input-wrapper .ax-editor-container{--tw-border-style: none;border-style:none;background-color:transparent!important;padding:calc(var(--spacing, .25rem) * 0);--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container ax-text-area{line-height:2}ax-conversation-composer .composer-input-wrapper .ax-editor-container:after{display:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container:hover:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error),ax-conversation-composer .composer-input-wrapper .ax-editor-container:focus-within:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error){--tw-border-style: none;border-style:none;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input{max-height:120px;min-height:calc(var(--spacing, .25rem) * 10);width:100%;resize:none;border-radius:1.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.9375rem;--tw-leading: var(--leading-normal, 1.5);line-height:var(--leading-normal, 1.5);--tw-outline-style: none;outline-style:none;font-variant-emoji:emoji;transition:border-color .2s}ax-conversation-composer .composer-input:focus{border-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-attachments{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-attachment{position:relative;display:flex;max-width:11rem;flex-shrink:0;align-items:center}ax-conversation-composer .ax-conversation-composer-attachment--media .ax-conversation-composer-attachment__thumb{position:relative;display:flex;height:calc(var(--spacing, .25rem) * 11);width:calc(var(--spacing, .25rem) * 11);align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-surface))}ax-conversation-composer .ax-conversation-composer-attachment__thumb img,ax-conversation-composer .ax-conversation-composer-attachment__thumb video{height:100%;width:100%;object-fit:cover}ax-conversation-composer .ax-conversation-composer-attachment--file{height:calc(var(--spacing, .25rem) * 11);max-width:12.5rem;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-surface));padding-inline-start:calc(var(--spacing, .25rem) * 2);padding-inline-end:calc(var(--spacing, .25rem) * 7)}ax-conversation-composer .ax-conversation-composer-attachment__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface));opacity:80%}ax-conversation-composer .ax-conversation-composer-attachment__name{min-width:calc(var(--spacing, .25rem) * 0);flex:1;overflow:hidden;font-size:.8125rem;text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface))}ax-conversation-composer .ax-conversation-composer-attachment__progress{pointer-events:none;position:absolute;inset:calc(var(--spacing, .25rem) * 0);border-radius:var(--radius-lg, .5rem);background:rgba(var(--ax-sys-color-on-surface),.18)}ax-conversation-composer .ax-conversation-composer-attachment--error{border-color:rgba(var(--ax-sys-color-danger-500))}ax-conversation-composer .ax-conversation-composer-attachment__remove{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * -1.5);top:calc(var(--spacing, .25rem) * -1.5);z-index:1;display:flex;height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 5);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;background-color:rgba(var(--ax-sys-color-danger-500));padding:calc(var(--spacing, .25rem) * 0);font-size:.625rem;color:rgba(var(--ax-sys-color-lightest-surface));opacity:0;pointer-events:none;transition:opacity .15s ease}ax-conversation-composer .ax-conversation-composer-attachment:hover .ax-conversation-composer-attachment__remove,ax-conversation-composer .ax-conversation-composer-attachment:focus-within .ax-conversation-composer-attachment__remove,ax-conversation-composer .ax-conversation-composer-attachment__remove:focus-visible{opacity:1;pointer-events:auto}@media(hover:none){ax-conversation-composer .ax-conversation-composer-attachment__remove{opacity:1;pointer-events:auto}}ax-conversation-composer .ax-conversation-composer-attachment-add{display:flex;height:calc(var(--spacing, .25rem) * 11);width:calc(var(--spacing, .25rem) * 11);flex-shrink:0;cursor:pointer;align-items:center;justify-content:center;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-surface));transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-attachment-add:hover:not(:disabled){background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-attachment-add:disabled{cursor:default;opacity:40%}ax-conversation-composer .composer-component-fullwidth{min-height:72px;width:100%;background-color:rgba(var(--ax-sys-color-lightest-surface))}ax-conversation-composer .composer-emoji-popover{width:100%}ax-conversation-composer .ax-conversation-composer-primary--stopping .fa-spinner{animation:ax-conversation-composer-spin .75s linear infinite}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-tracking: initial;--tw-leading: initial;--tw-outline-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXConversationRegistryComponentOutletComponent, selector: "ax-conversation-registry-component-outlet", inputs: ["component", "componentLoader", "inputs", "skeleton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXCommonModule }, { kind: "directive", type: i2.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
8155
8803
  }
8156
8804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationComposerComponent, decorators: [{
8157
8805
  type: Component,
@@ -8170,7 +8818,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
8170
8818
  AXButtonItemComponent,
8171
8819
  AXButtonItemListComponent,
8172
8820
  AXDecoratorModule,
8173
- ], template: "@if (activeConversation()) {\n <div class=\"composer\">\n <!-- Edit/Reply Banner -->\n @if (editingMessage() || replyingToMessage()) {\n <div\n class=\"ax-conversation-composer-banner\"\n [class.ax-conversation-composer-banner--edit]=\"!!editingMessage()\"\n [class.ax-conversation-composer-banner--reply]=\"!!replyingToMessage()\"\n >\n <div class=\"ax-conversation-composer-banner__accent\" aria-hidden=\"true\"></div>\n @if (editingMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-pen-to-square\"></i\n ></span>\n <div class=\"ax-conversation-composer-banner__body\">\n <span class=\"ax-conversation-composer-banner__label\">{{\n '@acorex:chat.composer.editing-message' | translate | async\n }}</span>\n @if (getEditingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n } @else if (replyingToMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-reply\"></i\n ></span>\n <div\n class=\"ax-conversation-composer-banner__body ax-conversation-composer-banner__body--clickable\"\n (click)=\"onReplyPreviewClick()\"\n >\n <span class=\"ax-conversation-composer-banner__label\">\n {{ '@acorex:chat.composer.replying-to' | translate | async }} {{ getReplyingSenderName() }}\n </span>\n @if (getReplyingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n }\n <ax-button\n class=\"ax-conversation-composer-banner__close rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.cancel')\"\n (onClick)=\"cancelEditReply()\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n\n <!-- Input Area -->\n <div class=\"composer-input-container\">\n <!-- Start actions -->\n <div class=\"composer-actions-left\">\n @if (startMenuActions().length > 0) {\n <span\n #attachMenuButton\n class=\"composer-attach-menu-trigger\"\n (mouseenter)=\"onAttachMenuMouseEnter()\"\n (mouseleave)=\"onAttachMenuMouseLeave()\"\n >\n <ax-button\n class=\"rounded-full text-xl\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"('@acorex:chat.tooltips.attach-file' | translate | async) ?? ''\"\n (onClick)=\"onAttachMenuClick($event)\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-paperclip\"></i>\n </ax-prefix>\n </ax-button>\n </span>\n }\n\n @for (action of startInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <!-- Text Input -->\n <div class=\"composer-input-wrapper\">\n <ax-text-area\n #inputElement\n [ngModel]=\"draftText()\"\n (ngModelChange)=\"onDraftModelChange($event)\"\n (onKeyDown)=\"onKeyDown($event)\"\n (onValueChanged)=\"onDraftValueChanged($event)\"\n [placeholder]=\"placeholder()\"\n [rows]=\"inputRows()\"\n [axAutoFocus]=\"true\"\n ></ax-text-area>\n </div>\n\n <!-- End actions -->\n <div class=\"composer-actions-right\">\n @for (action of endInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n\n <div class=\"composer-primary-button-slot\">\n @switch (primaryButtonMode()) {\n @case ('cancel') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-icon [class]=\"getPrimaryButtonIcon()\"> </ax-icon>\n </ax-button>\n }\n @case ('stopping') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"true\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @case ('send') {\n <ax-button\n class=\"rounded-full composer-primary-button--send\"\n [iconOnly]=\"true\"\n look=\"blank\"\n color=\"primary\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @default {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Attachments Preview -->\n @if (attachments().length > 0) {\n <div class=\"composer-attachments\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item\">\n <span class=\"attachment-icon\"><i class=\"fa-light fa-paperclip\"></i></span>\n <span class=\"attachment-name\">{{ attachment.name }}</span>\n <ax-button\n class=\"attachment-remove rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.remove-attachment')\"\n (onClick)=\"removeAttachment($index)\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- Popover for attachment menu -->\n@if (attachMenuTarget()) {\n <ax-popover\n #attachPopover\n [target]=\"attachMenuTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n >\n <div\n class=\"composer-attach-menu-panel\"\n (mouseenter)=\"onAttachMenuPanelMouseEnter()\"\n (mouseleave)=\"onAttachMenuPanelMouseLeave()\"\n >\n <ax-button-item-list>\n @for (action of startMenuActions(); track action.id) {\n <ax-button-item\n [text]=\"getActionLabel(action)\"\n (click)=\"onAttachMenuAction(action.id)\"\n [disabled]=\"!isActionEnabled(action)\"\n >\n <ax-prefix>\n <i [class]=\"action.icon\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </div>\n </ax-popover>\n}\n\n<!-- Popover for emoji/sticker picker -->\n@if (emojiPopoverTarget()) {\n <ax-popover\n #emojiPopover\n [target]=\"emojiPopoverTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n panelClass=\"composer-emoji-popover-panel\"\n (onClosed)=\"onEmojiPopoverClosed()\"\n >\n <div class=\"composer-emoji-popover\">\n <ax-conversation-registry-component-outlet\n [componentLoader]=\"composerPopupLoader\"\n [inputs]=\"getEmojiPopupInputs()\"\n />\n </div>\n </ax-popover>\n}\n", styles: ["@layer properties;@layer components{ax-conversation-composer{display:block;width:100%;font-variant-emoji:emoji;@keyframes ax-conversation-composer-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}}ax-conversation-composer .ax-conversation-composer-banner{display:flex;min-height:2.75rem;align-items:stretch;gap:calc(var(--spacing, .25rem) * 0);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface))}ax-conversation-composer .ax-conversation-composer-banner__accent{width:3px;flex-shrink:0;border-start-end-radius:var(--radius-sm, .25rem);border-end-end-radius:var(--radius-sm, .25rem);background-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__accent{background-color:rgba(var(--ax-sys-color-secondary-500))}ax-conversation-composer .ax-conversation-composer-banner__content{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-banner__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);font-size:.8125rem;color:rgba(var(--ax-sys-color-primary-600));background:rgba(var(--ax-sys-color-primary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__icon{color:rgba(var(--ax-sys-color-secondary-600));background:rgba(var(--ax-sys-color-secondary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner__body{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}ax-conversation-composer .ax-conversation-composer-banner__body--clickable{cursor:pointer;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__body--clickable:hover{opacity:.85}}ax-conversation-composer .ax-conversation-composer-banner__label{font-size:.6875rem;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:rgba(var(--ax-sys-color-primary-600));text-transform:uppercase}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__label{color:rgba(var(--ax-sys-color-secondary-600))}ax-conversation-composer .ax-conversation-composer-banner__preview{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);overflow:hidden;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface));opacity:.88}ax-conversation-composer .ax-conversation-composer-banner__preview i{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:70%}ax-conversation-composer .ax-conversation-composer-banner__close{margin-inline-end:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;align-self:center}ax-conversation-composer .ax-conversation-composer-banner__close>button{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);cursor:pointer;touch-action:manipulation;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-primary-lightest-surface),.55);box-shadow:none;background-image:none;transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__close:hover>button{color:rgba(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-banner__close>button:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .emoji-icon{flex-shrink:0;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}ax-conversation-composer .composer-input-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1)}ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-icon i,:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-prefix i{font-size:1.375rem;--tw-leading: 1;line-height:1}ax-conversation-composer .composer-attach-menu-trigger{display:inline-flex}ax-conversation-composer .composer-primary-button-slot{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);flex-shrink:0;align-items:center;justify-content:center}ax-conversation-composer .composer-primary-button-slot .composer-primary-button ax-prefix i{transition:opacity .15s ease}ax-conversation-composer .composer-primary-button-slot .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}@media(hover:hover){ax-conversation-composer .composer-actions-left ax-button>button:hover:not(:disabled),ax-conversation-composer .composer-actions-right ax-button:not(.composer-primary-button--send)>button:hover:not(:disabled){color:rgba(var(--ax-sys-color-on-surface),.68);background:rgba(var(--ax-sys-color-on-surface),.05)}}ax-conversation-composer .composer-input-wrapper{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;--tw-border-style: none;border-style:none;--tw-outline-style: none;outline-style:none}ax-conversation-composer .composer-input-wrapper textarea{resize:none;font-variant-emoji:emoji}ax-conversation-composer .composer-input-wrapper .ax-editor-container{--tw-border-style: none;border-style:none;background-color:transparent!important;padding:calc(var(--spacing, .25rem) * 0);--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container ax-text-area{line-height:2}ax-conversation-composer .composer-input-wrapper .ax-editor-container:after{display:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container:hover:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error),ax-conversation-composer .composer-input-wrapper .ax-editor-container:focus-within:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error){--tw-border-style: none;border-style:none;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input{max-height:120px;min-height:calc(var(--spacing, .25rem) * 10);width:100%;resize:none;border-radius:1.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.9375rem;--tw-leading: var(--leading-normal, 1.5);line-height:var(--leading-normal, 1.5);--tw-outline-style: none;outline-style:none;font-variant-emoji:emoji;transition:border-color .2s}ax-conversation-composer .composer-input:focus{border-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .composer-attachments{display:flex;flex-wrap:wrap;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);padding-bottom:calc(var(--spacing, .25rem) * 4)}ax-conversation-composer .attachment-item{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);background-color:rgba(var(--ax-sys-color-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}ax-conversation-composer .attachment-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}ax-conversation-composer .attachment-name{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-composer .attachment-remove,ax-conversation-composer .attachment-remove>button{display:flex;height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 5);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));box-shadow:none;background-image:none;transition:background .2s}@media(hover:hover){ax-conversation-composer .attachment-remove:hover>button,ax-conversation-composer .attachment-remove>button:hover{background-color:rgba(var(--ax-sys-color-danger-lightest-surface));color:rgba(var(--ax-sys-color-danger-500))}}ax-conversation-composer .composer-component-fullwidth{min-height:72px;width:100%;background-color:rgba(var(--ax-sys-color-lightest-surface))}ax-conversation-composer .composer-emoji-popover{width:100%}ax-conversation-composer .ax-conversation-composer-primary--stopping .fa-spinner{animation:ax-conversation-composer-spin .75s linear infinite}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-tracking: initial;--tw-leading: initial;--tw-outline-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
8821
+ ], template: "@if (activeConversation()) {\n <div class=\"composer\">\n <!-- Edit/Reply Banner -->\n @if (editingMessage() || replyingToMessage()) {\n <div\n class=\"ax-conversation-composer-banner\"\n [class.ax-conversation-composer-banner--edit]=\"!!editingMessage()\"\n [class.ax-conversation-composer-banner--reply]=\"!!replyingToMessage()\"\n >\n <div class=\"ax-conversation-composer-banner__accent\" aria-hidden=\"true\"></div>\n @if (editingMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-pen-to-square\"></i\n ></span>\n <div class=\"ax-conversation-composer-banner__body\">\n <span class=\"ax-conversation-composer-banner__label\">{{\n '@acorex:chat.composer.editing-message' | translate | async\n }}</span>\n @if (getEditingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n } @else if (replyingToMessage()) {\n <div class=\"ax-conversation-composer-banner__content\">\n <span class=\"ax-conversation-composer-banner__icon\" aria-hidden=\"true\"\n ><i class=\"fa-light fa-reply\"></i\n ></span>\n <div\n class=\"ax-conversation-composer-banner__body ax-conversation-composer-banner__body--clickable\"\n (click)=\"onReplyPreviewClick()\"\n >\n <span class=\"ax-conversation-composer-banner__label\">\n {{ '@acorex:chat.composer.replying-to' | translate | async }} {{ getReplyingSenderName() }}\n </span>\n @if (getReplyingPreview(); as preview) {\n <span class=\"ax-conversation-composer-banner__preview\">\n @if (preview.type !== 'text') {\n <i [class]=\"preview.icon\"></i>\n }\n {{ getComposerPreviewLabel(preview) }}\n </span>\n }\n </div>\n </div>\n }\n <ax-button\n class=\"ax-conversation-composer-banner__close rounded-full\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"translation.translateSync('@acorex:chat.actions.cancel')\"\n (onClick)=\"cancelEditReply()\"\n >\n <ax-icon><i class=\"fa-solid fa-xmark\"></i></ax-icon>\n </ax-button>\n </div>\n }\n\n @if (usesAttachmentBanner() && draftAttachments().length > 0) {\n <div class=\"ax-conversation-composer-attachments\" role=\"list\">\n @for (attachment of draftAttachments(); track attachment.id) {\n <div\n class=\"ax-conversation-composer-attachment\"\n role=\"listitem\"\n [class.ax-conversation-composer-attachment--media]=\"attachment.kind === 'image' || attachment.kind === 'video'\"\n [class.ax-conversation-composer-attachment--file]=\"attachment.kind === 'audio' || attachment.kind === 'file'\"\n [class.ax-conversation-composer-attachment--uploading]=\"attachment.uploading\"\n [class.ax-conversation-composer-attachment--error]=\"!!attachment.error\"\n [title]=\"attachment.file.name\"\n >\n @if (attachment.kind === 'image' || attachment.kind === 'video') {\n <span class=\"ax-conversation-composer-attachment__thumb\" aria-hidden=\"true\">\n @if (attachment.kind === 'video' && attachment.preview) {\n <video [src]=\"attachment.preview\" muted playsinline preload=\"metadata\"></video>\n } @else if (attachment.preview) {\n <img [src]=\"attachment.preview\" alt=\"\" />\n } @else {\n <i [class]=\"attachment.icon\"></i>\n }\n </span>\n } @else {\n <span class=\"ax-conversation-composer-attachment__icon\" aria-hidden=\"true\">\n <i [class]=\"attachment.icon\"></i>\n </span>\n <span class=\"ax-conversation-composer-attachment__name\">{{\n draftAttachmentLabel(attachment.file.name)\n }}</span>\n }\n @if (attachment.uploading) {\n <span class=\"ax-conversation-composer-attachment__progress\" aria-hidden=\"true\"></span>\n }\n <button\n type=\"button\"\n class=\"ax-conversation-composer-attachment__remove\"\n [attr.aria-label]=\"translation.translateSync('@acorex:chat.actions.remove-attachment')\"\n (click)=\"removeDraftAttachment(attachment.id); $event.stopPropagation()\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <button\n type=\"button\"\n class=\"ax-conversation-composer-attachment-add\"\n [disabled]=\"!canAddDraftAttachments()\"\n [attr.aria-label]=\"translation.translateSync('@acorex:chat.pickers.common.add-more')\"\n (click)=\"addDraftAttachments()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </button>\n </div>\n }\n\n <!-- Input Area -->\n <div class=\"composer-input-container\">\n <!-- Start actions -->\n <div class=\"composer-actions-left\">\n @if (startMenuActions().length > 0) {\n <span\n #attachMenuButton\n class=\"composer-attach-menu-trigger\"\n (mouseenter)=\"onAttachMenuMouseEnter()\"\n (mouseleave)=\"onAttachMenuMouseLeave()\"\n >\n <ax-button\n class=\"rounded-full text-xl\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"('@acorex:chat.tooltips.attach-file' | translate | async) ?? ''\"\n (onClick)=\"onAttachMenuClick($event)\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-paperclip\"></i>\n </ax-prefix>\n </ax-button>\n </span>\n }\n\n @for (action of startInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n\n <!-- Text Input -->\n <div class=\"composer-input-wrapper\">\n <ax-text-area\n #inputElement\n [ngModel]=\"draftText()\"\n (ngModelChange)=\"onDraftModelChange($event)\"\n (onKeyDown)=\"onKeyDown($event)\"\n (onValueChanged)=\"onDraftValueChanged($event)\"\n [placeholder]=\"placeholder()\"\n [rows]=\"inputRows()\"\n [axAutoFocus]=\"true\"\n ></ax-text-area>\n </div>\n\n <!-- End actions -->\n <div class=\"composer-actions-right\">\n @for (action of endInlineActions(); track action.id) {\n <ax-button\n look=\"blank\"\n [iconOnly]=\"true\"\n [text]=\"getActionLabel(action)\"\n [disabled]=\"!isActionEnabled(action)\"\n [class]=\"getActionButtonClass(action)\"\n (onClick)=\"onActionClick(action.id, $event)\"\n >\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-button>\n }\n\n <div class=\"composer-primary-button-slot\">\n @switch (primaryButtonMode()) {\n @case ('cancel') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-icon [class]=\"getPrimaryButtonIcon()\"> </ax-icon>\n </ax-button>\n }\n @case ('stopping') {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"true\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @case ('send') {\n <ax-button\n class=\"rounded-full composer-primary-button--send\"\n [iconOnly]=\"true\"\n look=\"blank\"\n color=\"primary\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n @default {\n <ax-button\n class=\"rounded-full\"\n [iconOnly]=\"true\"\n look=\"blank\"\n [text]=\"getPrimaryButtonLabel()\"\n [disabled]=\"isPrimaryButtonDisabled()\"\n (onClick)=\"onPrimaryButtonClick()\"\n >\n <ax-prefix>\n <i [class]=\"getPrimaryButtonIcon()\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n </div>\n </div>\n </div>\n </div>\n}\n\n<!-- Popover for attachment menu -->\n@if (attachMenuTarget()) {\n <ax-popover\n #attachPopover\n [target]=\"attachMenuTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n >\n <div\n class=\"composer-attach-menu-panel\"\n (mouseenter)=\"onAttachMenuPanelMouseEnter()\"\n (mouseleave)=\"onAttachMenuPanelMouseLeave()\"\n >\n <ax-button-item-list>\n @for (action of startMenuActions(); track action.id) {\n <ax-button-item\n [text]=\"getActionLabel(action)\"\n (click)=\"onAttachMenuAction(action.id)\"\n [disabled]=\"!isActionEnabled(action)\"\n >\n <ax-prefix>\n <i [class]=\"action.icon\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </div>\n </ax-popover>\n}\n\n<!-- Popover for emoji/sticker picker -->\n@if (emojiPopoverTarget()) {\n <ax-popover\n #emojiPopover\n [target]=\"emojiPopoverTarget()\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'top-start'\"\n panelClass=\"composer-emoji-popover-panel\"\n (onClosed)=\"onEmojiPopoverClosed()\"\n >\n <div class=\"composer-emoji-popover\">\n <ax-conversation-registry-component-outlet\n [componentLoader]=\"composerPopupLoader\"\n [inputs]=\"getEmojiPopupInputs()\"\n />\n </div>\n </ax-popover>\n}\n", styles: ["@layer properties;@layer components{ax-conversation-composer{display:block;width:100%;font-variant-emoji:emoji;@keyframes ax-conversation-composer-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}}ax-conversation-composer .ax-conversation-composer-banner{display:flex;min-height:2.75rem;align-items:stretch;gap:calc(var(--spacing, .25rem) * 0);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface))}ax-conversation-composer .ax-conversation-composer-banner__accent{width:3px;flex-shrink:0;border-start-end-radius:var(--radius-sm, .25rem);border-end-end-radius:var(--radius-sm, .25rem);background-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__accent{background-color:rgba(var(--ax-sys-color-secondary-500))}ax-conversation-composer .ax-conversation-composer-banner__content{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-banner__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);font-size:.8125rem;color:rgba(var(--ax-sys-color-primary-600));background:rgba(var(--ax-sys-color-primary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__icon{color:rgba(var(--ax-sys-color-secondary-600));background:rgba(var(--ax-sys-color-secondary-500),.1)}ax-conversation-composer .ax-conversation-composer-banner__body{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}ax-conversation-composer .ax-conversation-composer-banner__body--clickable{cursor:pointer;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__body--clickable:hover{opacity:.85}}ax-conversation-composer .ax-conversation-composer-banner__label{font-size:.6875rem;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);color:rgba(var(--ax-sys-color-primary-600));text-transform:uppercase}ax-conversation-composer .ax-conversation-composer-banner--reply .ax-conversation-composer-banner__label{color:rgba(var(--ax-sys-color-secondary-600))}ax-conversation-composer .ax-conversation-composer-banner__preview{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);overflow:hidden;font-size:.8125rem;--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface));opacity:.88}ax-conversation-composer .ax-conversation-composer-banner__preview i{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:70%}ax-conversation-composer .ax-conversation-composer-banner__close{margin-inline-end:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;align-self:center}ax-conversation-composer .ax-conversation-composer-banner__close>button{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);cursor:pointer;touch-action:manipulation;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius);--tw-border-style: none;border-style:none;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-primary-lightest-surface),.55);box-shadow:none;background-image:none;transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-banner__close:hover>button{color:rgba(var(--ax-sys-color-on-surface));background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-banner__close>button:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .emoji-icon{flex-shrink:0;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}ax-conversation-composer .composer-input-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);background-color:rgba(var(--ax-sys-color-lightest-surface));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1)}ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-icon i,:is(ax-conversation-composer .composer-actions-left,ax-conversation-composer .composer-actions-right) ax-prefix i{font-size:1.375rem;--tw-leading: 1;line-height:1}ax-conversation-composer .composer-attach-menu-trigger{display:inline-flex}ax-conversation-composer .composer-primary-button-slot{display:flex;height:calc(var(--spacing, .25rem) * 9);width:calc(var(--spacing, .25rem) * 9);flex-shrink:0;align-items:center;justify-content:center}ax-conversation-composer .composer-primary-button-slot .composer-primary-button ax-prefix i{transition:opacity .15s ease}ax-conversation-composer .composer-primary-button-slot .fa-paper-plane-top:dir(rtl){transform:scaleX(-1)}@media(hover:hover){ax-conversation-composer .composer-actions-left ax-button>button:hover:not(:disabled),ax-conversation-composer .composer-actions-right ax-button:not(.composer-primary-button--send)>button:hover:not(:disabled){color:rgba(var(--ax-sys-color-on-surface),.68);background:rgba(var(--ax-sys-color-on-surface),.05)}}ax-conversation-composer .composer-input-wrapper{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;--tw-border-style: none;border-style:none;--tw-outline-style: none;outline-style:none}ax-conversation-composer .composer-input-wrapper textarea{resize:none;font-variant-emoji:emoji}ax-conversation-composer .composer-input-wrapper .ax-editor-container{--tw-border-style: none;border-style:none;background-color:transparent!important;padding:calc(var(--spacing, .25rem) * 0);--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container ax-text-area{line-height:2}ax-conversation-composer .composer-input-wrapper .ax-editor-container:after{display:none}ax-conversation-composer .composer-input-wrapper .ax-editor-container:hover:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error),ax-conversation-composer .composer-input-wrapper .ax-editor-container:focus-within:not(.ax-state-disabled,.ax-state-readonly,.ax-state-error){--tw-border-style: none;border-style:none;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style: none;outline-style:none;background-image:none}ax-conversation-composer .composer-input{max-height:120px;min-height:calc(var(--spacing, .25rem) * 10);width:100%;resize:none;border-radius:1.25rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.9375rem;--tw-leading: var(--leading-normal, 1.5);line-height:var(--leading-normal, 1.5);--tw-outline-style: none;outline-style:none;font-variant-emoji:emoji;transition:border-color .2s}ax-conversation-composer .composer-input:focus{border-color:rgba(var(--ax-sys-color-primary-surface))}ax-conversation-composer .ax-conversation-composer-attachments{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-block-style:var(--tw-border-style);border-block-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-light-surface));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}ax-conversation-composer .ax-conversation-composer-attachment{position:relative;display:flex;max-width:11rem;flex-shrink:0;align-items:center}ax-conversation-composer .ax-conversation-composer-attachment--media .ax-conversation-composer-attachment__thumb{position:relative;display:flex;height:calc(var(--spacing, .25rem) * 11);width:calc(var(--spacing, .25rem) * 11);align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-surface))}ax-conversation-composer .ax-conversation-composer-attachment__thumb img,ax-conversation-composer .ax-conversation-composer-attachment__thumb video{height:100%;width:100%;object-fit:cover}ax-conversation-composer .ax-conversation-composer-attachment--file{height:calc(var(--spacing, .25rem) * 11);max-width:12.5rem;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:rgba(var(--ax-sys-color-surface));padding-inline-start:calc(var(--spacing, .25rem) * 2);padding-inline-end:calc(var(--spacing, .25rem) * 7)}ax-conversation-composer .ax-conversation-composer-attachment__icon{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface));opacity:80%}ax-conversation-composer .ax-conversation-composer-attachment__name{min-width:calc(var(--spacing, .25rem) * 0);flex:1;overflow:hidden;font-size:.8125rem;text-overflow:ellipsis;white-space:nowrap;color:rgba(var(--ax-sys-color-on-surface))}ax-conversation-composer .ax-conversation-composer-attachment__progress{pointer-events:none;position:absolute;inset:calc(var(--spacing, .25rem) * 0);border-radius:var(--radius-lg, .5rem);background:rgba(var(--ax-sys-color-on-surface),.18)}ax-conversation-composer .ax-conversation-composer-attachment--error{border-color:rgba(var(--ax-sys-color-danger-500))}ax-conversation-composer .ax-conversation-composer-attachment__remove{position:absolute;inset-inline-end:calc(var(--spacing, .25rem) * -1.5);top:calc(var(--spacing, .25rem) * -1.5);z-index:1;display:flex;height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 5);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);--tw-border-style: none;border-style:none;background-color:rgba(var(--ax-sys-color-danger-500));padding:calc(var(--spacing, .25rem) * 0);font-size:.625rem;color:rgba(var(--ax-sys-color-lightest-surface));opacity:0;pointer-events:none;transition:opacity .15s ease}ax-conversation-composer .ax-conversation-composer-attachment:hover .ax-conversation-composer-attachment__remove,ax-conversation-composer .ax-conversation-composer-attachment:focus-within .ax-conversation-composer-attachment__remove,ax-conversation-composer .ax-conversation-composer-attachment__remove:focus-visible{opacity:1;pointer-events:auto}@media(hover:none){ax-conversation-composer .ax-conversation-composer-attachment__remove{opacity:1;pointer-events:auto}}ax-conversation-composer .ax-conversation-composer-attachment-add{display:flex;height:calc(var(--spacing, .25rem) * 11);width:calc(var(--spacing, .25rem) * 11);flex-shrink:0;cursor:pointer;align-items:center;justify-content:center;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:rgba(var(--ax-sys-color-border-light-surface));background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-on-surface));transition:background-color .15s ease,color .15s ease}@media(hover:hover){ax-conversation-composer .ax-conversation-composer-attachment-add:hover:not(:disabled){background:rgba(var(--ax-sys-color-on-surface),.06)}}ax-conversation-composer .ax-conversation-composer-attachment-add:disabled{cursor:default;opacity:40%}ax-conversation-composer .composer-component-fullwidth{min-height:72px;width:100%;background-color:rgba(var(--ax-sys-color-lightest-surface))}ax-conversation-composer .composer-emoji-popover{width:100%}ax-conversation-composer .ax-conversation-composer-primary--stopping .fa-spinner{animation:ax-conversation-composer-spin .75s linear infinite}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-tracking: initial;--tw-leading: initial;--tw-outline-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
8174
8822
  }], ctorParameters: () => [], propDecorators: { textAreaRef: [{ type: i0.ViewChild, args: ['inputElement', { ...{ read: AXTextAreaComponent }, isSignal: true }] }], messageSent: [{ type: i0.Output, args: ["messageSent"] }], generationCancelled: [{ type: i0.Output, args: ["generationCancelled"] }], emojiClick: [{ type: i0.Output, args: ["emojiClick"] }], attachClick: [{ type: i0.Output, args: ["attachClick"] }], voiceClick: [{ type: i0.Output, args: ["voiceClick"] }], emojiPopoverRef: [{ type: i0.ViewChild, args: ['emojiPopover', { isSignal: true }] }], attachPopoverRef: [{ type: i0.ViewChild, args: ['attachPopover', { isSignal: true }] }], attachMenuButtonRef: [{ type: i0.ViewChild, args: ['attachMenuButton', { isSignal: true }] }] } });
8175
8823
 
8176
8824
  /**
@@ -12034,94 +12682,33 @@ function createConversationAudioFileType() {
12034
12682
  const items = audio.audios.map((item) => ({
12035
12683
  url: item.url?.trim(),
12036
12684
  title: item.title?.trim(),
12037
- }));
12038
- return {
12039
- text: caption ?? '',
12040
- meta: { kind: 'audio', caption, items, count: audio.audios.length },
12041
- };
12042
- },
12043
- };
12044
- }
12045
- class AXConversationAudioFileTypeProvider extends AXFileTypeInfoProvider {
12046
- items() {
12047
- return Promise.resolve([createConversationAudioFileType()]);
12048
- }
12049
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
12050
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, providedIn: 'root' }); }
12051
- }
12052
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, decorators: [{
12053
- type: Injectable,
12054
- args: [{ providedIn: 'root' }]
12055
- }] });
12056
-
12057
- var conversationAudio_fileType = /*#__PURE__*/Object.freeze({
12058
- __proto__: null,
12059
- AXConversationAudioFileTypeProvider: AXConversationAudioFileTypeProvider,
12060
- AX_CONVERSATION_AUDIO_CATALOG: AX_CONVERSATION_AUDIO_CATALOG,
12061
- AX_CONVERSATION_AUDIO_PRESENTATION: AX_CONVERSATION_AUDIO_PRESENTATION,
12062
- conversationAudioUtilities: conversationAudioUtilities,
12063
- createConversationAudioFileType: createConversationAudioFileType
12064
- });
12065
-
12066
- function audioItemFromUpload(file, result, duration) {
12067
- const url = resolvePersistableMediaUrl(result.url);
12068
- const item = {
12069
- mediaId: result.mediaId,
12070
- mimeType: result.mimeType,
12071
- size: result.size,
12072
- duration,
12073
- title: file.name,
12074
- metadata: result.metadata,
12075
- };
12076
- if (url) {
12077
- item.url = url;
12078
- }
12079
- return item;
12080
- }
12081
- function mergeAudioUploadResult(payload, result) {
12082
- const base = normalizeAudioPayload(payload);
12083
- const audios = [...base.audios];
12084
- const i = audios.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
12085
- const slot = i >= 0 ? audios[i] : undefined;
12086
- const url = resolvePersistableMediaUrl(result.url);
12087
- const next = {
12088
- ...(slot ?? { duration: 0 }),
12089
- mediaId: result.mediaId,
12090
- mimeType: result.mimeType,
12091
- size: result.size,
12092
- metadata: result.metadata,
12093
- };
12094
- if (url) {
12095
- next.url = url;
12096
- }
12097
- if (i >= 0)
12098
- audios[i] = next;
12099
- else
12100
- audios.push(next);
12101
- return { ...base, type: 'audio', audios };
12102
- }
12103
- function applyAudioLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
12104
- const base = normalizeAudioPayload(payload);
12105
- const audios = [...base.audios];
12106
- const slot = audios.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
12107
- const preview = { url: localUrl, duration: 0, mimeType };
12108
- if (slot >= 0) {
12109
- audios[slot] = { ...audios[slot], ...preview };
12110
- }
12111
- else if (audios.length === 0) {
12112
- audios.push(preview);
12113
- }
12114
- else {
12115
- audios[0] = { ...audios[0], ...preview };
12685
+ }));
12686
+ return {
12687
+ text: caption ?? '',
12688
+ meta: { kind: 'audio', caption, items, count: audio.audios.length },
12689
+ };
12690
+ },
12691
+ };
12692
+ }
12693
+ class AXConversationAudioFileTypeProvider extends AXFileTypeInfoProvider {
12694
+ items() {
12695
+ return Promise.resolve([createConversationAudioFileType()]);
12116
12696
  }
12117
- return { ...base, type: 'audio', audios };
12697
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
12698
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, providedIn: 'root' }); }
12118
12699
  }
12700
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationAudioFileTypeProvider, decorators: [{
12701
+ type: Injectable,
12702
+ args: [{ providedIn: 'root' }]
12703
+ }] });
12119
12704
 
12120
- var audioComposer_payload = /*#__PURE__*/Object.freeze({
12705
+ var conversationAudio_fileType = /*#__PURE__*/Object.freeze({
12121
12706
  __proto__: null,
12122
- applyAudioLocalPreview: applyAudioLocalPreview,
12123
- audioItemFromUpload: audioItemFromUpload,
12124
- mergeAudioUploadResult: mergeAudioUploadResult
12707
+ AXConversationAudioFileTypeProvider: AXConversationAudioFileTypeProvider,
12708
+ AX_CONVERSATION_AUDIO_CATALOG: AX_CONVERSATION_AUDIO_CATALOG,
12709
+ AX_CONVERSATION_AUDIO_PRESENTATION: AX_CONVERSATION_AUDIO_PRESENTATION,
12710
+ conversationAudioUtilities: conversationAudioUtilities,
12711
+ createConversationAudioFileType: createConversationAudioFileType
12125
12712
  });
12126
12713
 
12127
12714
  /**
@@ -12337,17 +12924,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
12337
12924
  args: [{ selector: 'ax-conversation-picker-options', encapsulation: ViewEncapsulation.None, imports: [AsyncPipe, AXCheckBoxComponent, AXLabelComponent, AXTranslationModule, FormsModule], template: "<div class=\"ax-conversation-picker-options\">\n @if (showGroupItems()) {\n <ax-check-box [(ngModel)]=\"groupItems\" [color]=\"'primary'\">\n <ax-label>{{ '@acorex:chat.pickers.common.group-items' | translate | async }}</ax-label>\n </ax-check-box>\n }\n\n @if (showSendAsDocuments()) {\n <ax-check-box [(ngModel)]=\"sendAsDocuments\" [color]=\"'primary'\">\n <ax-label>{{ '@acorex:chat.pickers.common.send-as-documents' | translate | async }}</ax-label>\n </ax-check-box>\n }\n</div>\n", styles: ["@layer components{ax-conversation-picker-options{display:block;width:100%;flex-shrink:0}ax-conversation-picker-options .ax-conversation-picker-options{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 2)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
12338
12925
  }], propDecorators: { showGroupItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGroupItems", required: false }] }], showSendAsDocuments: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSendAsDocuments", required: false }] }], groupItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupItems", required: false }] }, { type: i0.Output, args: ["groupItemsChange"] }], sendAsDocuments: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendAsDocuments", required: false }] }, { type: i0.Output, args: ["sendAsDocumentsChange"] }] } });
12339
12926
 
12340
- /** Middle-ellipsis truncation for long file names in picker rows. */
12341
- function truncatePickerFileName(text, maxLength = 36) {
12342
- if (text.length <= maxLength) {
12343
- return text;
12344
- }
12345
- const keep = maxLength - 3;
12346
- const start = Math.ceil(keep / 2);
12347
- const end = Math.floor(keep / 2);
12348
- return `${text.slice(0, start)}...${text.slice(text.length - end)}`;
12349
- }
12350
-
12351
12927
  /** Creates a new File instance with an updated display name. */
12352
12928
  function renamePickerFileObject(file, nextName) {
12353
12929
  const trimmed = nextName.trim();
@@ -12487,74 +13063,6 @@ function installComposerPickerAutoRun(host) {
12487
13063
  });
12488
13064
  }
12489
13065
 
12490
- function fileItemFromUpload(file, result, extras) {
12491
- const extension = file.name.includes('.') ? file.name.split('.').pop() : undefined;
12492
- const url = resolvePersistableMediaUrl(result.url);
12493
- const duration = extras?.duration != null && Number.isFinite(extras.duration) ? extras.duration : undefined;
12494
- const item = {
12495
- mediaId: result.mediaId,
12496
- mimeType: result.mimeType,
12497
- size: result.size,
12498
- name: file.name,
12499
- thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
12500
- extension,
12501
- duration,
12502
- metadata: result.metadata,
12503
- };
12504
- if (url) {
12505
- item.url = url;
12506
- }
12507
- return item;
12508
- }
12509
- function mergeFileUploadResult(payload, result) {
12510
- const base = normalizeFilePayload(payload);
12511
- const files = [...base.files];
12512
- const i = files.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
12513
- const slot = i >= 0 ? files[i] : undefined;
12514
- const name = slot?.name ?? result.metadata?.['fileName'] ?? 'file';
12515
- const url = resolvePersistableMediaUrl(result.url);
12516
- const next = {
12517
- ...(slot ?? { name, mimeType: result.mimeType }),
12518
- mediaId: result.mediaId,
12519
- mimeType: result.mimeType,
12520
- size: result.size,
12521
- name,
12522
- thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl ?? slot?.thumbnailUrl, url),
12523
- metadata: result.metadata,
12524
- };
12525
- if (url) {
12526
- next.url = url;
12527
- }
12528
- if (i >= 0)
12529
- files[i] = next;
12530
- else
12531
- files.push(next);
12532
- return { ...base, type: 'file', files };
12533
- }
12534
- function applyFileLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
12535
- const base = normalizeFilePayload(payload);
12536
- const files = [...base.files];
12537
- const slot = files.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
12538
- const preview = { url: localUrl, name: 'upload', mimeType };
12539
- if (slot >= 0) {
12540
- files[slot] = { ...files[slot], ...preview };
12541
- }
12542
- else if (files.length === 0) {
12543
- files.push(preview);
12544
- }
12545
- else {
12546
- files[0] = { ...files[0], ...preview };
12547
- }
12548
- return { ...base, type: 'file', files };
12549
- }
12550
-
12551
- var fileComposer_payload = /*#__PURE__*/Object.freeze({
12552
- __proto__: null,
12553
- applyFileLocalPreview: applyFileLocalPreview,
12554
- fileItemFromUpload: fileItemFromUpload,
12555
- mergeFileUploadResult: mergeFileUploadResult
12556
- });
12557
-
12558
13066
  /**
12559
13067
  * Audio Picker Component
12560
13068
  * Full-width audio file selection interface for the composer
@@ -12721,7 +13229,7 @@ class AXConversationAudioPickerComponent {
12721
13229
  if (!item) {
12722
13230
  return;
12723
13231
  }
12724
- const { AXConversationPickerRenameFileDialogComponent } = await import('./acorex-components-conversation-picker-rename-file-dialog.component-BlGupvO5.mjs');
13232
+ const { AXConversationPickerRenameFileDialogComponent } = await import('./acorex-components-conversation-picker-rename-file-dialog.component-C1lV6aI2.mjs');
12725
13233
  const result = await this.popupService.open(AXConversationPickerRenameFileDialogComponent, {
12726
13234
  title: this.translation.translateSync('@acorex:chat.pickers.files.rename-title'),
12727
13235
  size: 'sm',
@@ -13342,7 +13850,7 @@ class AXConversationFilePickerComponent {
13342
13850
  if (!item) {
13343
13851
  return;
13344
13852
  }
13345
- const { AXConversationPickerRenameFileDialogComponent } = await import('./acorex-components-conversation-picker-rename-file-dialog.component-BlGupvO5.mjs');
13853
+ const { AXConversationPickerRenameFileDialogComponent } = await import('./acorex-components-conversation-picker-rename-file-dialog.component-C1lV6aI2.mjs');
13346
13854
  const result = await this.popupService.open(AXConversationPickerRenameFileDialogComponent, {
13347
13855
  title: this.translation.translateSync('@acorex:chat.pickers.files.rename-title'),
13348
13856
  size: 'sm',
@@ -13693,92 +14201,10 @@ var conversationImage_fileType = /*#__PURE__*/Object.freeze({
13693
14201
  createConversationImageFileType: createConversationImageFileType
13694
14202
  });
13695
14203
 
13696
- const EMPTY = { width: 0, height: 0, duration: 0 };
13697
- async function probeImageDimensions(source) {
13698
- if (typeof createImageBitmap === 'function' && typeof source !== 'string') {
13699
- try {
13700
- const bitmap = await createImageBitmap(source);
13701
- const size = { width: bitmap.width, height: bitmap.height };
13702
- bitmap.close();
13703
- if (size.width > 0 && size.height > 0) {
13704
- return size;
13705
- }
13706
- }
13707
- catch {
13708
- // Fall through to HTMLImageElement.
13709
- }
13710
- }
13711
- return new Promise((resolve) => {
13712
- const img = new Image();
13713
- let objectUrl = '';
13714
- const finish = (width, height) => {
13715
- if (objectUrl) {
13716
- URL.revokeObjectURL(objectUrl);
13717
- }
13718
- resolve({ width, height });
13719
- };
13720
- img.onload = () => finish(img.naturalWidth, img.naturalHeight);
13721
- img.onerror = () => finish(0, 0);
13722
- if (typeof source === 'string') {
13723
- img.src = source;
13724
- return;
13725
- }
13726
- objectUrl = URL.createObjectURL(source);
13727
- img.src = objectUrl;
13728
- });
13729
- }
13730
- async function probeVideoMedia(source) {
13731
- if (typeof document === 'undefined') {
13732
- return EMPTY;
13733
- }
13734
- return new Promise((resolve) => {
13735
- const el = document.createElement('video');
13736
- el.preload = 'metadata';
13737
- const objectUrl = URL.createObjectURL(source);
13738
- const finish = (dims) => {
13739
- URL.revokeObjectURL(objectUrl);
13740
- el.src = '';
13741
- resolve(dims);
13742
- };
13743
- el.onloadedmetadata = () => {
13744
- finish({
13745
- width: el.videoWidth || 0,
13746
- height: el.videoHeight || 0,
13747
- duration: Number.isFinite(el.duration) ? el.duration : 0,
13748
- });
13749
- };
13750
- el.onerror = () => finish(EMPTY);
13751
- el.src = objectUrl;
13752
- });
13753
- }
13754
-
13755
- var mediaDimensions = /*#__PURE__*/Object.freeze({
13756
- __proto__: null,
13757
- probeImageDimensions: probeImageDimensions,
13758
- probeVideoMedia: probeVideoMedia
13759
- });
13760
-
13761
14204
  /**
13762
14205
  * Image Picker Component
13763
14206
  * Full-width image selection and preview interface for the composer
13764
14207
  */
13765
- async function imageItemFromUpload(file, result) {
13766
- const url = resolvePersistableMediaUrl(result.url);
13767
- const size = await probeImageDimensions(file);
13768
- const item = {
13769
- mediaId: result.mediaId,
13770
- mimeType: result.mimeType,
13771
- size: result.size,
13772
- thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
13773
- width: size.width,
13774
- height: size.height,
13775
- metadata: result.metadata,
13776
- };
13777
- if (url) {
13778
- item.url = url;
13779
- }
13780
- return item;
13781
- }
13782
14208
  class AXConversationImagePickerComponent {
13783
14209
  get composerService() {
13784
14210
  const svc = this.service() ?? this.composerServiceFromInjector;
@@ -14568,73 +14994,6 @@ var conversationVideo_fileType = /*#__PURE__*/Object.freeze({
14568
14994
  createConversationVideoFileType: createConversationVideoFileType
14569
14995
  });
14570
14996
 
14571
- async function videoItemFromUpload(file, result, duration, size) {
14572
- const url = resolvePersistableMediaUrl(result.url);
14573
- const probed = size?.width && size.height
14574
- ? { width: size.width, height: size.height, duration }
14575
- : await probeVideoMedia(file);
14576
- const item = {
14577
- mediaId: result.mediaId,
14578
- mimeType: result.mimeType,
14579
- size: result.size,
14580
- thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl, url),
14581
- duration: duration || probed.duration,
14582
- width: probed.width,
14583
- height: probed.height,
14584
- metadata: result.metadata,
14585
- };
14586
- if (url) {
14587
- item.url = url;
14588
- }
14589
- return item;
14590
- }
14591
- function mergeVideoUploadResult(payload, result) {
14592
- const base = normalizeVideoPayload(payload);
14593
- const videos = [...base.videos];
14594
- const i = videos.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
14595
- const slot = i >= 0 ? videos[i] : undefined;
14596
- const url = resolvePersistableMediaUrl(result.url);
14597
- const next = {
14598
- ...(slot ?? { duration: 0, width: 0, height: 0 }),
14599
- mediaId: result.mediaId,
14600
- mimeType: result.mimeType,
14601
- size: result.size,
14602
- thumbnailUrl: resolvePersistedThumbnailUrl(result.thumbnailUrl ?? slot?.thumbnailUrl, url),
14603
- metadata: result.metadata,
14604
- };
14605
- if (url) {
14606
- next.url = url;
14607
- }
14608
- if (i >= 0)
14609
- videos[i] = next;
14610
- else
14611
- videos.push(next);
14612
- return { ...base, type: 'video', videos };
14613
- }
14614
- function applyVideoLocalPreview(payload, localUrl, mimeType = 'application/octet-stream') {
14615
- const base = normalizeVideoPayload(payload);
14616
- const videos = [...base.videos];
14617
- const slot = videos.findIndex((x) => !x.mediaId && !resolvePersistableMediaUrl(x.url));
14618
- const preview = { url: localUrl, duration: 0, width: 0, height: 0, mimeType };
14619
- if (slot >= 0) {
14620
- videos[slot] = { ...videos[slot], ...preview };
14621
- }
14622
- else if (videos.length === 0) {
14623
- videos.push(preview);
14624
- }
14625
- else {
14626
- videos[0] = { ...videos[0], ...preview };
14627
- }
14628
- return { ...base, type: 'video', videos };
14629
- }
14630
-
14631
- var videoComposer_payload = /*#__PURE__*/Object.freeze({
14632
- __proto__: null,
14633
- applyVideoLocalPreview: applyVideoLocalPreview,
14634
- mergeVideoUploadResult: mergeVideoUploadResult,
14635
- videoItemFromUpload: videoItemFromUpload
14636
- });
14637
-
14638
14997
  /**
14639
14998
  * Video Picker Component
14640
14999
  * Full-width video selection and preview interface for the composer
@@ -17558,7 +17917,7 @@ class AXConversationLocationRendererComponent extends AXConversationMessageRende
17558
17917
  });
17559
17918
  }
17560
17919
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationLocationRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
17561
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXConversationLocationRendererComponent, isStandalone: true, selector: "ax-conversation-location-renderer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "mapHost", first: true, predicate: ["mapHost"], descendants: true, isSignal: true }, { propertyName: "map", first: true, predicate: AXMapComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-conversation-loc\">\n <ax-conversation-message-renderer-state [rendererState]=\"rendererState()\" [message]=\"message()\" />\n <div #mapHost class=\"ax-conversation-loc__map\" [class.ax-conversation-loc__map--fullscreen]=\"mapIsFullscreen()\">\n <ax-map\n [latitude]=\"latitude()\"\n [longitude]=\"longitude()\"\n [zoomLevel]=\"15\"\n [markers]=\"markers()\"\n [hasLocator]=\"false\"\n [hasDraw]=\"false\"\n (onMapReady)=\"scheduleMapResize()\"\n ></ax-map>\n <ax-button\n class=\"ax-conversation-loc__map-fs ax-sm rounded-full\"\n look=\"solid\"\n [iconOnly]=\"true\"\n [text]=\"mapFullscreenLabel()\"\n [attr.aria-label]=\"mapFullscreenLabel()\"\n [attr.title]=\"mapFullscreenLabel()\"\n (onClick)=\"toggleMapFullscreen($event)\"\n >\n <ax-icon>\n <i [class]=\"mapFullscreenIconClass()\" aria-hidden=\"true\"></i>\n </ax-icon>\n </ax-button>\n </div>\n <ax-button\n class=\"ax-conversation-loc__action\"\n look=\"blank\"\n [text]=\"'@acorex:chat.actions.open-in-maps'\"\n (onClick)=\"openInMaps($event)\"\n >\n <ax-suffix>\n <i class=\"fa-light fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n </ax-suffix>\n </ax-button>\n <div class=\"ax-conversation-loc__body\">\n <div class=\"ax-conversation-loc__title\">\n <span class=\"ax-conversation-loc__title-text\">{{ locationName() }}</span>\n </div>\n @if (address()) {\n <div class=\"ax-conversation-loc__addr\">{{ address() }}</div>\n }\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-conversation-location-renderer{display:block;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);width:min(22.5rem,85cqi)}ax-conversation-location-renderer .ax-conversation-loc{display:flex;width:100%;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;overflow:hidden;color:inherit}ax-conversation-location-renderer .ax-conversation-loc__map{position:relative;width:100%;overflow:hidden;aspect-ratio:16 / 10;height:auto;max-height:min(40dvh,16rem)}ax-conversation-location-renderer .ax-conversation-loc__body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 1);background-color:var(--color-surface);color:var(--color-on-surface);border-color:var(--color-border-surface);padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 2.5);padding-bottom:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__title{display:flex;align-items:center;font-size:.9375rem;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}ax-conversation-location-renderer .ax-conversation-loc__title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-location-renderer .ax-conversation-loc__addr{overflow:hidden;font-size:.875rem;text-overflow:ellipsis;white-space:nowrap;opacity:.78}ax-conversation-location-renderer .ax-conversation-loc__meta{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__coords{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:.6875rem;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:60%}ax-conversation-location-renderer .ax-conversation-loc__action{display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-conversation-location-renderer .ax-conversation-loc__action>button{min-height:calc(var(--spacing, .25rem) * 11);width:100%;touch-action:manipulation;justify-content:space-between;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.8125rem;color:inherit;opacity:.9}ax-conversation-location-renderer .ax-conversation-loc__action i{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:85%}.ax-conversation-loc__map{position:relative;overflow:hidden}.ax-conversation-loc__map ax-map{display:block;height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map .ax-map-container,.ax-conversation-loc__map .leaflet-container{height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map-fs{position:absolute;z-index:99999;inset-block-start:.375rem;inset-inline-end:.375rem}.ax-conversation-loc__map--fullscreen{width:100%;height:100%;max-height:none;aspect-ratio:auto;border-radius:0}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXMapModule }, { kind: "component", type: i1$5.AXMapComponent, selector: "ax-map", inputs: ["zoomLevel", "latitude", "longitude", "maxMarker", "maxPolygon", "maxPolyline", "maxRectangle", "maxCircle", "hasDraw", "hasLocator", "fitToDraw", "limitDraw", "addPoiToFitDraw", "addMarkerOnTap", "readonly", "disabled", "markerPlace", "locatePlace", "poiMinZoom", "markers", "polygons", "polylines", "rectangles", "circles", "pois"], outputs: ["zoomLevelChange", "latitudeChange", "longitudeChange", "onMarkerAdded", "onMarkerClick", "onMarkerChanged", "onPolygonAdded", "onPolygonClick", "onPolygonChanged", "onPolylineAdded", "onPolylineClick", "onPolylineChanged", "onRectangleAdded", "onRectangleClick", "onRectangleChanged", "onCircleAdded", "onCircleClick", "onCircleChanged", "onLocationFound", "onPoiChanged", "onPoiAdded", "onMapReady", "onLoadError"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXConversationMessageRendererStateComponent, selector: "ax-conversation-message-renderer-state", inputs: ["rendererState", "message", "contentErrorLabel", "deliveryFailedLabel", "showContentErrorChrome", "contentErrorStyle", "contentErrorIconClass", "placement", "contentRetryEnabled"], outputs: ["contentRetry"] }, { kind: "ngmodule", type: AXTranslationModule }], encapsulation: i0.ViewEncapsulation.None }); }
17920
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXConversationLocationRendererComponent, isStandalone: true, selector: "ax-conversation-location-renderer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "mapHost", first: true, predicate: ["mapHost"], descendants: true, isSignal: true }, { propertyName: "map", first: true, predicate: AXMapComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-conversation-loc\">\n <ax-conversation-message-renderer-state [rendererState]=\"rendererState()\" [message]=\"message()\" />\n <div #mapHost class=\"ax-conversation-loc__map\" [class.ax-conversation-loc__map--fullscreen]=\"mapIsFullscreen()\">\n <ax-map\n [latitude]=\"latitude()\"\n [longitude]=\"longitude()\"\n [zoomLevel]=\"15\"\n [markers]=\"markers()\"\n [hasLocator]=\"false\"\n [hasDraw]=\"false\"\n (onMapReady)=\"scheduleMapResize()\"\n ></ax-map>\n <ax-button\n class=\"ax-conversation-loc__map-fs ax-sm rounded-full\"\n look=\"solid\"\n [iconOnly]=\"true\"\n [text]=\"mapFullscreenLabel()\"\n [attr.aria-label]=\"mapFullscreenLabel()\"\n [attr.title]=\"mapFullscreenLabel()\"\n (onClick)=\"toggleMapFullscreen($event)\"\n >\n <ax-icon>\n <i [class]=\"mapFullscreenIconClass()\" aria-hidden=\"true\"></i>\n </ax-icon>\n </ax-button>\n </div>\n <ax-button\n class=\"ax-conversation-loc__action rounded-none\"\n look=\"blank\"\n [text]=\"'@acorex:chat.actions.open-in-maps'\"\n (onClick)=\"openInMaps($event)\"\n >\n <ax-suffix>\n <i class=\"fa-light fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n </ax-suffix>\n </ax-button>\n <div class=\"ax-conversation-loc__body\">\n <div class=\"ax-conversation-loc__title\">\n <span class=\"ax-conversation-loc__title-text\">{{ locationName() }}</span>\n </div>\n @if (address()) {\n <div class=\"ax-conversation-loc__addr\">{{ address() }}</div>\n }\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-conversation-location-renderer{display:block;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);width:min(22.5rem,85cqi)}ax-conversation-location-renderer .ax-conversation-loc{display:flex;width:100%;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;overflow:hidden;color:inherit}ax-conversation-location-renderer .ax-conversation-loc__map{position:relative;width:100%;overflow:hidden;aspect-ratio:16 / 10;height:auto;max-height:min(40dvh,16rem)}ax-conversation-location-renderer .ax-conversation-loc__body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 1);background-color:var(--color-surface);color:var(--color-on-surface);border-color:var(--color-border-surface);padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 2.5);padding-bottom:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__title{display:flex;align-items:center;font-size:.9375rem;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}ax-conversation-location-renderer .ax-conversation-loc__title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-location-renderer .ax-conversation-loc__addr{overflow:hidden;font-size:.875rem;text-overflow:ellipsis;white-space:nowrap;opacity:.78}ax-conversation-location-renderer .ax-conversation-loc__meta{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__coords{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:.6875rem;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:60%}ax-conversation-location-renderer .ax-conversation-loc__action{display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0);border-radius:0}ax-conversation-location-renderer .ax-conversation-loc__action>button{min-height:calc(var(--spacing, .25rem) * 11);width:100%;touch-action:manipulation;justify-content:space-between;border-radius:0;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.8125rem;opacity:.9;--ax-comp-ripple-color: currentColor}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button{--ax-comp-ripple-color: color-mix(in srgb, currentColor 25%, transparent)}}ax-conversation-location-renderer .ax-conversation-loc__action i{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:85%}.ax-conversation-loc__map{position:relative;overflow:hidden}.ax-conversation-loc__map ax-map{display:block;height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map .ax-map-container,.ax-conversation-loc__map .leaflet-container{height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map-fs{position:absolute;z-index:99999;inset-block-start:.375rem;inset-inline-end:.375rem}.ax-conversation-loc__map--fullscreen{width:100%;height:100%;max-height:none;aspect-ratio:auto;border-radius:0}}ax-conversation-location-renderer .ax-conversation-loc__action>button{color:inherit;background-color:transparent;background-image:none;box-shadow:none;transform:none}@media(hover:hover){ax-conversation-location-renderer .ax-conversation-loc__action>button:hover:not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;opacity:1;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:hover:not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 12%,transparent)}}}ax-conversation-location-renderer .ax-conversation-loc__action>button:is(:focus,:focus-within,:focus-visible,.ax-state-focus):not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:is(:focus,:focus-within,:focus-visible,.ax-state-focus):not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 10%,transparent)}}ax-conversation-location-renderer .ax-conversation-loc__action>button:active:not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;opacity:1;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:active:not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 18%,transparent)}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXMapModule }, { kind: "component", type: i1$5.AXMapComponent, selector: "ax-map", inputs: ["zoomLevel", "latitude", "longitude", "maxMarker", "maxPolygon", "maxPolyline", "maxRectangle", "maxCircle", "hasDraw", "hasLocator", "fitToDraw", "limitDraw", "addPoiToFitDraw", "addMarkerOnTap", "readonly", "disabled", "markerPlace", "locatePlace", "poiMinZoom", "markers", "polygons", "polylines", "rectangles", "circles", "pois"], outputs: ["zoomLevelChange", "latitudeChange", "longitudeChange", "onMarkerAdded", "onMarkerClick", "onMarkerChanged", "onPolygonAdded", "onPolygonClick", "onPolygonChanged", "onPolylineAdded", "onPolylineClick", "onPolylineChanged", "onRectangleAdded", "onRectangleClick", "onRectangleChanged", "onCircleAdded", "onCircleClick", "onCircleChanged", "onLocationFound", "onPoiChanged", "onPoiAdded", "onMapReady", "onLoadError"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXConversationMessageRendererStateComponent, selector: "ax-conversation-message-renderer-state", inputs: ["rendererState", "message", "contentErrorLabel", "deliveryFailedLabel", "showContentErrorChrome", "contentErrorStyle", "contentErrorIconClass", "placement", "contentRetryEnabled"], outputs: ["contentRetry"] }, { kind: "ngmodule", type: AXTranslationModule }], encapsulation: i0.ViewEncapsulation.None }); }
17562
17921
  }
17563
17922
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXConversationLocationRendererComponent, decorators: [{
17564
17923
  type: Component,
@@ -17570,7 +17929,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
17570
17929
  AXDecoratorIconComponent,
17571
17930
  AXConversationMessageRendererStateComponent,
17572
17931
  AXTranslationModule,
17573
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"ax-conversation-loc\">\n <ax-conversation-message-renderer-state [rendererState]=\"rendererState()\" [message]=\"message()\" />\n <div #mapHost class=\"ax-conversation-loc__map\" [class.ax-conversation-loc__map--fullscreen]=\"mapIsFullscreen()\">\n <ax-map\n [latitude]=\"latitude()\"\n [longitude]=\"longitude()\"\n [zoomLevel]=\"15\"\n [markers]=\"markers()\"\n [hasLocator]=\"false\"\n [hasDraw]=\"false\"\n (onMapReady)=\"scheduleMapResize()\"\n ></ax-map>\n <ax-button\n class=\"ax-conversation-loc__map-fs ax-sm rounded-full\"\n look=\"solid\"\n [iconOnly]=\"true\"\n [text]=\"mapFullscreenLabel()\"\n [attr.aria-label]=\"mapFullscreenLabel()\"\n [attr.title]=\"mapFullscreenLabel()\"\n (onClick)=\"toggleMapFullscreen($event)\"\n >\n <ax-icon>\n <i [class]=\"mapFullscreenIconClass()\" aria-hidden=\"true\"></i>\n </ax-icon>\n </ax-button>\n </div>\n <ax-button\n class=\"ax-conversation-loc__action\"\n look=\"blank\"\n [text]=\"'@acorex:chat.actions.open-in-maps'\"\n (onClick)=\"openInMaps($event)\"\n >\n <ax-suffix>\n <i class=\"fa-light fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n </ax-suffix>\n </ax-button>\n <div class=\"ax-conversation-loc__body\">\n <div class=\"ax-conversation-loc__title\">\n <span class=\"ax-conversation-loc__title-text\">{{ locationName() }}</span>\n </div>\n @if (address()) {\n <div class=\"ax-conversation-loc__addr\">{{ address() }}</div>\n }\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-conversation-location-renderer{display:block;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);width:min(22.5rem,85cqi)}ax-conversation-location-renderer .ax-conversation-loc{display:flex;width:100%;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;overflow:hidden;color:inherit}ax-conversation-location-renderer .ax-conversation-loc__map{position:relative;width:100%;overflow:hidden;aspect-ratio:16 / 10;height:auto;max-height:min(40dvh,16rem)}ax-conversation-location-renderer .ax-conversation-loc__body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 1);background-color:var(--color-surface);color:var(--color-on-surface);border-color:var(--color-border-surface);padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 2.5);padding-bottom:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__title{display:flex;align-items:center;font-size:.9375rem;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}ax-conversation-location-renderer .ax-conversation-loc__title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-location-renderer .ax-conversation-loc__addr{overflow:hidden;font-size:.875rem;text-overflow:ellipsis;white-space:nowrap;opacity:.78}ax-conversation-location-renderer .ax-conversation-loc__meta{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__coords{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:.6875rem;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:60%}ax-conversation-location-renderer .ax-conversation-loc__action{display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-conversation-location-renderer .ax-conversation-loc__action>button{min-height:calc(var(--spacing, .25rem) * 11);width:100%;touch-action:manipulation;justify-content:space-between;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.8125rem;color:inherit;opacity:.9}ax-conversation-location-renderer .ax-conversation-loc__action i{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:85%}.ax-conversation-loc__map{position:relative;overflow:hidden}.ax-conversation-loc__map ax-map{display:block;height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map .ax-map-container,.ax-conversation-loc__map .leaflet-container{height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map-fs{position:absolute;z-index:99999;inset-block-start:.375rem;inset-inline-end:.375rem}.ax-conversation-loc__map--fullscreen{width:100%;height:100%;max-height:none;aspect-ratio:auto;border-radius:0}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
17932
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"ax-conversation-loc\">\n <ax-conversation-message-renderer-state [rendererState]=\"rendererState()\" [message]=\"message()\" />\n <div #mapHost class=\"ax-conversation-loc__map\" [class.ax-conversation-loc__map--fullscreen]=\"mapIsFullscreen()\">\n <ax-map\n [latitude]=\"latitude()\"\n [longitude]=\"longitude()\"\n [zoomLevel]=\"15\"\n [markers]=\"markers()\"\n [hasLocator]=\"false\"\n [hasDraw]=\"false\"\n (onMapReady)=\"scheduleMapResize()\"\n ></ax-map>\n <ax-button\n class=\"ax-conversation-loc__map-fs ax-sm rounded-full\"\n look=\"solid\"\n [iconOnly]=\"true\"\n [text]=\"mapFullscreenLabel()\"\n [attr.aria-label]=\"mapFullscreenLabel()\"\n [attr.title]=\"mapFullscreenLabel()\"\n (onClick)=\"toggleMapFullscreen($event)\"\n >\n <ax-icon>\n <i [class]=\"mapFullscreenIconClass()\" aria-hidden=\"true\"></i>\n </ax-icon>\n </ax-button>\n </div>\n <ax-button\n class=\"ax-conversation-loc__action rounded-none\"\n look=\"blank\"\n [text]=\"'@acorex:chat.actions.open-in-maps'\"\n (onClick)=\"openInMaps($event)\"\n >\n <ax-suffix>\n <i class=\"fa-light fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n </ax-suffix>\n </ax-button>\n <div class=\"ax-conversation-loc__body\">\n <div class=\"ax-conversation-loc__title\">\n <span class=\"ax-conversation-loc__title-text\">{{ locationName() }}</span>\n </div>\n @if (address()) {\n <div class=\"ax-conversation-loc__addr\">{{ address() }}</div>\n }\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-conversation-location-renderer{display:block;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);width:min(22.5rem,85cqi)}ax-conversation-location-renderer .ax-conversation-loc{display:flex;width:100%;max-width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;overflow:hidden;color:inherit}ax-conversation-location-renderer .ax-conversation-loc__map{position:relative;width:100%;overflow:hidden;aspect-ratio:16 / 10;height:auto;max-height:min(40dvh,16rem)}ax-conversation-location-renderer .ax-conversation-loc__body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 1);background-color:var(--color-surface);color:var(--color-on-surface);border-color:var(--color-border-surface);padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 2.5);padding-bottom:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__title{display:flex;align-items:center;font-size:.9375rem;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}ax-conversation-location-renderer .ax-conversation-loc__title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ax-conversation-location-renderer .ax-conversation-loc__addr{overflow:hidden;font-size:.875rem;text-overflow:ellipsis;white-space:nowrap;opacity:.78}ax-conversation-location-renderer .ax-conversation-loc__meta{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-conversation-location-renderer .ax-conversation-loc__coords{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:.6875rem;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:60%}ax-conversation-location-renderer .ax-conversation-loc__action{display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0);border-radius:0}ax-conversation-location-renderer .ax-conversation-loc__action>button{min-height:calc(var(--spacing, .25rem) * 11);width:100%;touch-action:manipulation;justify-content:space-between;border-radius:0;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:.8125rem;opacity:.9;--ax-comp-ripple-color: currentColor}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button{--ax-comp-ripple-color: color-mix(in srgb, currentColor 25%, transparent)}}ax-conversation-location-renderer .ax-conversation-loc__action i{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));opacity:85%}.ax-conversation-loc__map{position:relative;overflow:hidden}.ax-conversation-loc__map ax-map{display:block;height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map .ax-map-container,.ax-conversation-loc__map .leaflet-container{height:100%;min-height:calc(var(--spacing, .25rem) * 0);width:100%;min-width:calc(var(--spacing, .25rem) * 0)}.ax-conversation-loc__map-fs{position:absolute;z-index:99999;inset-block-start:.375rem;inset-inline-end:.375rem}.ax-conversation-loc__map--fullscreen{width:100%;height:100%;max-height:none;aspect-ratio:auto;border-radius:0}}ax-conversation-location-renderer .ax-conversation-loc__action>button{color:inherit;background-color:transparent;background-image:none;box-shadow:none;transform:none}@media(hover:hover){ax-conversation-location-renderer .ax-conversation-loc__action>button:hover:not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;opacity:1;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:hover:not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 12%,transparent)}}}ax-conversation-location-renderer .ax-conversation-loc__action>button:is(:focus,:focus-within,:focus-visible,.ax-state-focus):not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:is(:focus,:focus-within,:focus-visible,.ax-state-focus):not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 10%,transparent)}}ax-conversation-location-renderer .ax-conversation-loc__action>button:active:not(:disabled,.ax-state-disabled,.ax-state-loading){color:inherit;opacity:1;background-color:currentColor;background-image:none;box-shadow:none;transform:none}@supports (color: color-mix(in lab,red,red)){ax-conversation-location-renderer .ax-conversation-loc__action>button:active:not(:disabled,.ax-state-disabled,.ax-state-loading){background-color:color-mix(in srgb,currentColor 18%,transparent)}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
17574
17933
  }], ctorParameters: () => [], propDecorators: { mapHost: [{ type: i0.ViewChild, args: ['mapHost', { isSignal: true }] }], map: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXMapComponent), { isSignal: true }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }] } });
17575
17934
 
17576
17935
  var locationRenderer_component = /*#__PURE__*/Object.freeze({
@@ -19168,5 +19527,5 @@ function getErrorMessage(code, params) {
19168
19527
  * Generated bundle index. Do not edit.
19169
19528
  */
19170
19529
 
19171
- export { AXConversationPickerCaptionComponent as $, AXConversationApi as A, AXConversationFileRendererComponent as B, AXConversationForwardMessageDialogComponent as C, AXConversationImageAttachmentComponent as D, AXConversationImageFileTypeProvider as E, AXConversationImagePickerComponent as F, AXConversationImageRendererComponent as G, AXConversationInfiniteScrollDirective as H, AXConversationInfoBarActionRegistry as I, AXConversationInfoBarComponent as J, AXConversationInfoBarSearchComponent as K, AXConversationInfoBarService as L, AXConversationItemActionRegistry as M, AXConversationLocationPickerComponent as N, AXConversationLocationRendererComponent as O, AXConversationMediaPlaybackInfoBarBannerComponent as P, AXConversationMessageActionRegistry as Q, AXConversationMessageApi as R, AXConversationMessageListComponent as S, AXConversationMessageListNoActiveDefaultComponent as T, AXConversationMessageListService as U, AXConversationMessageRendererCopyHostComponent as V, AXConversationMessageRendererRegistry as W, AXConversationMessageRendererStateComponent as X, AXConversationMessageUtilsService as Y, AXConversationModule as Z, AXConversationNewDialogComponent as _, AXConversationApiLoggerService as a, AX_CONVERSATION_IMAGE_CATALOG as a$, AXConversationPickerEmptyComponent as a0, AXConversationPickerFooterComponent as a1, AXConversationPickerHeaderComponent as a2, AXConversationPickerOptionsComponent as a3, AXConversationPickerShellComponent as a4, AXConversationPickerToolbarComponent as a5, AXConversationRealtimeApi as a6, AXConversationRegistryComponentOutletComponent as a7, AXConversationRegistryService as a8, AXConversationService as a9, AX_CONVERSATION_COMPOSER_VIDEO_ACTION as aA, AX_CONVERSATION_COMPOSER_VOICE_RECORDING_ACTION as aB, AX_CONVERSATION_CONFIG as aC, AX_CONVERSATION_CONNECTION_ERRORS as aD, AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT as aE, AX_CONVERSATION_DEFAULT_COMPOSER_ACTIONS as aF, AX_CONVERSATION_DEFAULT_COMPOSER_TABS as aG, AX_CONVERSATION_DEFAULT_CONVERSATION_ITEM_ACTIONS as aH, AX_CONVERSATION_DEFAULT_CONVERSATION_TABS as aI, AX_CONVERSATION_DEFAULT_GROUP_ICON as aJ, AX_CONVERSATION_DEFAULT_INFO_BAR_ACTIONS as aK, AX_CONVERSATION_DEFAULT_MESSAGE_ACTIONS as aL, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND as aM, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND_PRESET_ID as aN, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_THEME_BACKGROUND as aO, AX_CONVERSATION_DEFAULT_MESSAGE_RENDERERS as aP, AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES as aQ, AX_CONVERSATION_DEFAULT_USER_ICON as aR, AX_CONVERSATION_ERRORS as aS, AX_CONVERSATION_ERROR_HANDLER_CONFIG as aT, AX_CONVERSATION_ERROR_MESSAGES as aU, AX_CONVERSATION_FALLBACK_RENDERER as aV, AX_CONVERSATION_FILE_CATALOG as aW, AX_CONVERSATION_FILE_ERRORS as aX, AX_CONVERSATION_FILE_PRESENTATION as aY, AX_CONVERSATION_FILE_RENDERER as aZ, AX_CONVERSATION_FILE_TYPES_READY as a_, AXConversationSidebarComponent as aa, AXConversationSidebarService as ab, AXConversationStickerRendererComponent as ac, AXConversationStickerTabComponent as ad, AXConversationSystemRendererComponent as ae, AXConversationTabRegistry as af, AXConversationTextRendererComponent as ag, AXConversationUserApi as ah, AXConversationVideoAttachmentComponent as ai, AXConversationVideoFileTypeProvider as aj, AXConversationVideoPickerComponent as ak, AXConversationVideoRendererComponent as al, AXConversationVoiceFileTypeProvider as am, AXConversationVoiceRecorderComponent as an, AXConversationVoiceRendererComponent as ao, AX_CONVERSATION_AUDIO_CATALOG as ap, AX_CONVERSATION_AUDIO_PRESENTATION as aq, AX_CONVERSATION_AUDIO_RENDERER as ar, AX_CONVERSATION_BUILTIN_COMPOSER_TABS as as, AX_CONVERSATION_COMPOSER_AUDIO_ACTION as at, AX_CONVERSATION_COMPOSER_EMOJI_ACTION as au, AX_CONVERSATION_COMPOSER_EMOJI_TAB as av, AX_CONVERSATION_COMPOSER_FILE_ACTION as aw, AX_CONVERSATION_COMPOSER_IMAGE_ACTION as ax, AX_CONVERSATION_COMPOSER_LOCATION_ACTION as ay, AX_CONVERSATION_COMPOSER_STICKER_TAB as az, AXConversationAudioAttachmentComponent as b, copyWithFileTypeFallback as b$, AX_CONVERSATION_IMAGE_PRESENTATION as b0, AX_CONVERSATION_IMAGE_RENDERER as b1, AX_CONVERSATION_INFO_BAR_ARCHIVE_ACTION as b2, AX_CONVERSATION_INFO_BAR_BLOCK_ACTION as b3, AX_CONVERSATION_INFO_BAR_DELETE_ACTION as b4, AX_CONVERSATION_INFO_BAR_DIVIDER as b5, AX_CONVERSATION_INFO_BAR_MUTE_ACTION as b6, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION as b7, AX_CONVERSATION_ITEM_BLOCK_ACTION as b8, AX_CONVERSATION_ITEM_DELETE_ACTION as b9, AX_CONVERSATION_TEXT_RENDERER as bA, AX_CONVERSATION_URL_ERRORS as bB, AX_CONVERSATION_USER_AVATAR_COMPONENT as bC, AX_CONVERSATION_USER_ERRORS as bD, AX_CONVERSATION_VIDEO_CATALOG as bE, AX_CONVERSATION_VIDEO_PRESENTATION as bF, AX_CONVERSATION_VIDEO_RENDERER as bG, AX_CONVERSATION_VOICE_CATALOG as bH, AX_CONVERSATION_VOICE_PRESENTATION as bI, AX_CONVERSATION_VOICE_RENDERER as bJ, AX_DEFAULT_CONVERSATION_CONFIG as bK, abortPickerUploads as bL, applyAudioLocalPreview as bM, applyFileLocalPreview as bN, applyLocalPreview as bO, applyVideoLocalPreview as bP, applyVoiceLocalPreview as bQ, audioItemFromUpload as bR, bindMediaRendererContentState as bS, buildMediaGalleryTiles as bT, canShowRendererContentError as bU, cleanupPickerUploads as bV, conversationAudioUtilities as bW, conversationFileUtilities as bX, conversationImageUtilities as bY, conversationVideoUtilities as bZ, conversationVoiceUtilities as b_, AX_CONVERSATION_ITEM_DIVIDER as ba, AX_CONVERSATION_ITEM_MARK_READ_ACTION as bb, AX_CONVERSATION_ITEM_MUTE_ACTION as bc, AX_CONVERSATION_ITEM_PIN_ACTION as bd, AX_CONVERSATION_JUMBO_EMOJI_MAX as be, AX_CONVERSATION_LOCATION_ERRORS as bf, AX_CONVERSATION_LOCATION_RENDERER as bg, AX_CONVERSATION_MESSAGE_DELETE_ACTION as bh, AX_CONVERSATION_MESSAGE_EDIT_ACTION as bi, AX_CONVERSATION_MESSAGE_ERRORS as bj, AX_CONVERSATION_MESSAGE_FORWARD_ACTION as bk, AX_CONVERSATION_MESSAGE_LIST_BACKGROUND_PRESETS as bl, AX_CONVERSATION_MESSAGE_REPLY_ACTION as bm, AX_CONVERSATION_MESSAGE_TYPE_FILE_TYPE as bn, AX_CONVERSATION_PEER_AVATAR_TYPES as bo, AX_CONVERSATION_REGISTRY_CONFIG as bp, AX_CONVERSATION_STICKER_API_KEY as bq, AX_CONVERSATION_STICKER_RENDERER as br, AX_CONVERSATION_SYSTEM_RENDERER as bs, AX_CONVERSATION_TAB_ALL as bt, AX_CONVERSATION_TAB_ARCHIVED as bu, AX_CONVERSATION_TAB_BOT as bv, AX_CONVERSATION_TAB_CHANNELS as bw, AX_CONVERSATION_TAB_GROUPS as bx, AX_CONVERSATION_TAB_PRIVATE as by, AX_CONVERSATION_TAB_UNREAD as bz, AXConversationAudioFileTypeProvider as c, mergeWithDefaults as c$, countLoneEmojis as c0, createConversationAudioFileType as c1, createConversationFileFileType as c2, createConversationImageFileType as c3, createConversationVideoFileType as c4, createConversationVoiceFileType as c5, createLocalPreviewUrl as c6, createObjectUrl as c7, createPickerDragHandlers as c8, createPickerUploadItemId as c9, inferFileExtensionHintFromMessage as cA, isAttachmentListCategory as cB, isComposerTabEnabled as cC, isConversationReactionsEnabled as cD, isConversationRoomCreator as cE, isGenericPrivateConversationTitle as cF, isGridMediaCategory as cG, isGroupLikeConversation as cH, isJumboEmojiText as cI, isJumboEmojiTextMessage as cJ, isMessageDeliveryPending as cK, isMessageListThemeBackground as cL, isMessageVisibleAfterHistoryCutoff as cM, isNonPersistableMediaUrl as cN, isPickerItemReadyToSend as cO, isPlainChromeMessage as cP, isSameMessageListBackground as cQ, isUploadAborted as cR, limitFilesToCapacity as cS, listTextGraphemes as cT, mediaCopyText as cU, mergeAudioUploadResult as cV, mergeFileUploadResult as cW, mergeInfoPanelMessages as cX, mergeUploadResult as cY, mergeVideoUploadResult as cZ, mergeVoiceUploadResult as c_, createResolvedMediaUrlSignal as ca, deleteUploadedPickerMedia as cb, dismissComposerPickerHost as cc, ensureConversationFileCatalogRegistered as cd, fetchConversationMediaPage as ce, fileItemAsAudioMedia as cf, fileItemFromUpload as cg, filesFromClipboardEvent as ch, filterMessagesByMediaCategory as ci, filterSupplementalInfoPanelMessages as cj, findExistingPrivateConversation as ck, formatDuration as cl, formatErrorMessage as cm, formatFileByteSize as cn, formatFileSize as co, formatMediaDuration as cp, formatPickerValidationMessage as cq, getActiveComposerPickerPasteHandler as cr, getConversationMediaCategories as cs, getConversationProfileFields as ct, getErrorMessage as cu, getMessageAudioItems as cv, getMessageVideoItems as cw, getPickerCancelUploadLabel as cx, getPrivatePeerParticipant as cy, hasRegistryComponent as cz, AXConversationAudioPickerComponent as d, messageContainsLink as d0, normalizeAudioPayload as d1, normalizeFilePayload as d2, normalizeImagePayload as d3, normalizeMessageListBackgroundValue as d4, normalizeVideoPayload as d5, notifyMaxFilesCapacityExceeded as d6, notifyPickerValidationErrors as d7, openWithFileType as d8, pickDisplayMediaUrl as d9, resolvePersistedThumbnailUrl as dA, resolvePrivatePeerParticipant as dB, resolvePrivatePeerUserId as dC, resolveUserAvatarDisplay as dD, resolveVideoThumbnailUrl as dE, revokeObjectUrl as dF, revokePickerBlobPreviews as dG, sanitizeInput as dH, shouldUseUserAvatarForConversation as dI, sortUsersForForward as dJ, syncPlaybackInfoBarBanner as dK, toUploaderReference$1 as dL, toUploaderReference as dM, uploadPickerFile as dN, usesDefaultMessageListWallpaper as dO, validateConversationId as dP, validateEmail as dQ, validateLatitude as dR, validateLongitude as dS, validateMessagePayload as dT, validateMessageText as dU, validateMessageType as dV, validateUrl as dW, validateUserId as dX, validateUserIds as dY, videoItemFromUpload as dZ, pickEarliestJoinedParticipant as da, pickerItemToMediaReference as db, pickerItemToUploadResult as dc, probeImageDimensions as dd, probeVideoMedia as de, provideConversation as df, provideConversationComposerFileTypes as dg, provideConversationFileCatalog as dh, registerComposerPickerPasteHandler as di, reportMediaLoadError as dj, resolveComposerMaxFiles as dk, resolveConversationAvatarDisplay as dl, resolveConversationComposerTabs as dm, resolveConversationForViewer as dn, resolveConversationMessageFileType as dp, resolveConversationPeerParticipant as dq, resolveConversationPeerUserId as dr, resolveConversationTitleForViewer as ds, resolveGalleryImageUrl as dt, resolveImageDisplayUrl as du, resolveMessageChrome as dv, resolveMessageListBackgroundRaw as dw, resolveMessageListBackgroundStyle as dx, resolveParticipantProfile as dy, resolvePersistableMediaUrl as dz, AXConversationAudioRendererComponent as e, AXConversationAvatarComponent as f, AXConversationAvatarPickerComponent as g, AXConversationBaseRegistry as h, isValidPickerFileName as i, AXConversationComposerActionRegistry as j, AXConversationComposerComponent as k, AXConversationComposerFileTypesProvider as l, AXConversationComposerGenerationStateService as m, AXConversationComposerPopupComponent as n, AXConversationComposerService as o, AXConversationComposerTabRegistry as p, AXConversationContainerComponent as q, AXConversationContainerDirective as r, AXConversationDateUtilsService as s, AXConversationDeleteDialogComponent as t, AXConversationEmojiTabComponent as u, AXConversationErrorHandlerService as v, AXConversationFallbackRendererComponent as w, AXConversationFileAttachmentComponent as x, AXConversationFileFileTypeProvider as y, AXConversationFilePickerComponent as z };
19172
- //# sourceMappingURL=acorex-components-conversation-acorex-components-conversation-CObX5Gdf.mjs.map
19530
+ export { AXConversationPickerCaptionComponent as $, AXConversationApi as A, AXConversationFileRendererComponent as B, AXConversationForwardMessageDialogComponent as C, AXConversationImageAttachmentComponent as D, AXConversationImageFileTypeProvider as E, AXConversationImagePickerComponent as F, AXConversationImageRendererComponent as G, AXConversationInfiniteScrollDirective as H, AXConversationInfoBarActionRegistry as I, AXConversationInfoBarComponent as J, AXConversationInfoBarSearchComponent as K, AXConversationInfoBarService as L, AXConversationItemActionRegistry as M, AXConversationLocationPickerComponent as N, AXConversationLocationRendererComponent as O, AXConversationMediaPlaybackInfoBarBannerComponent as P, AXConversationMessageActionRegistry as Q, AXConversationMessageApi as R, AXConversationMessageListComponent as S, AXConversationMessageListNoActiveDefaultComponent as T, AXConversationMessageListService as U, AXConversationMessageRendererCopyHostComponent as V, AXConversationMessageRendererRegistry as W, AXConversationMessageRendererStateComponent as X, AXConversationMessageUtilsService as Y, AXConversationModule as Z, AXConversationNewDialogComponent as _, AXConversationApiLoggerService as a, AX_CONVERSATION_IMAGE_CATALOG as a$, AXConversationPickerEmptyComponent as a0, AXConversationPickerFooterComponent as a1, AXConversationPickerHeaderComponent as a2, AXConversationPickerOptionsComponent as a3, AXConversationPickerShellComponent as a4, AXConversationPickerToolbarComponent as a5, AXConversationRealtimeApi as a6, AXConversationRegistryComponentOutletComponent as a7, AXConversationRegistryService as a8, AXConversationService as a9, AX_CONVERSATION_COMPOSER_VIDEO_ACTION as aA, AX_CONVERSATION_COMPOSER_VOICE_RECORDING_ACTION as aB, AX_CONVERSATION_CONFIG as aC, AX_CONVERSATION_CONNECTION_ERRORS as aD, AX_CONVERSATION_CONVERSATION_AVATAR_COMPONENT as aE, AX_CONVERSATION_DEFAULT_COMPOSER_ACTIONS as aF, AX_CONVERSATION_DEFAULT_COMPOSER_TABS as aG, AX_CONVERSATION_DEFAULT_CONVERSATION_ITEM_ACTIONS as aH, AX_CONVERSATION_DEFAULT_CONVERSATION_TABS as aI, AX_CONVERSATION_DEFAULT_GROUP_ICON as aJ, AX_CONVERSATION_DEFAULT_INFO_BAR_ACTIONS as aK, AX_CONVERSATION_DEFAULT_MESSAGE_ACTIONS as aL, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND as aM, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_BACKGROUND_PRESET_ID as aN, AX_CONVERSATION_DEFAULT_MESSAGE_LIST_THEME_BACKGROUND as aO, AX_CONVERSATION_DEFAULT_MESSAGE_RENDERERS as aP, AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES as aQ, AX_CONVERSATION_DEFAULT_USER_ICON as aR, AX_CONVERSATION_ERRORS as aS, AX_CONVERSATION_ERROR_HANDLER_CONFIG as aT, AX_CONVERSATION_ERROR_MESSAGES as aU, AX_CONVERSATION_FALLBACK_RENDERER as aV, AX_CONVERSATION_FILE_CATALOG as aW, AX_CONVERSATION_FILE_ERRORS as aX, AX_CONVERSATION_FILE_PRESENTATION as aY, AX_CONVERSATION_FILE_RENDERER as aZ, AX_CONVERSATION_FILE_TYPES_READY as a_, AXConversationSidebarComponent as aa, AXConversationSidebarService as ab, AXConversationStickerRendererComponent as ac, AXConversationStickerTabComponent as ad, AXConversationSystemRendererComponent as ae, AXConversationTabRegistry as af, AXConversationTextRendererComponent as ag, AXConversationUserApi as ah, AXConversationVideoAttachmentComponent as ai, AXConversationVideoFileTypeProvider as aj, AXConversationVideoPickerComponent as ak, AXConversationVideoRendererComponent as al, AXConversationVoiceFileTypeProvider as am, AXConversationVoiceRecorderComponent as an, AXConversationVoiceRendererComponent as ao, AX_CONVERSATION_AUDIO_CATALOG as ap, AX_CONVERSATION_AUDIO_PRESENTATION as aq, AX_CONVERSATION_AUDIO_RENDERER as ar, AX_CONVERSATION_BUILTIN_COMPOSER_TABS as as, AX_CONVERSATION_COMPOSER_AUDIO_ACTION as at, AX_CONVERSATION_COMPOSER_EMOJI_ACTION as au, AX_CONVERSATION_COMPOSER_EMOJI_TAB as av, AX_CONVERSATION_COMPOSER_FILE_ACTION as aw, AX_CONVERSATION_COMPOSER_IMAGE_ACTION as ax, AX_CONVERSATION_COMPOSER_LOCATION_ACTION as ay, AX_CONVERSATION_COMPOSER_STICKER_TAB as az, AXConversationAudioAttachmentComponent as b, copyWithFileTypeFallback as b$, AX_CONVERSATION_IMAGE_PRESENTATION as b0, AX_CONVERSATION_IMAGE_RENDERER as b1, AX_CONVERSATION_INFO_BAR_ARCHIVE_ACTION as b2, AX_CONVERSATION_INFO_BAR_BLOCK_ACTION as b3, AX_CONVERSATION_INFO_BAR_DELETE_ACTION as b4, AX_CONVERSATION_INFO_BAR_DIVIDER as b5, AX_CONVERSATION_INFO_BAR_MUTE_ACTION as b6, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION as b7, AX_CONVERSATION_ITEM_BLOCK_ACTION as b8, AX_CONVERSATION_ITEM_DELETE_ACTION as b9, AX_CONVERSATION_TEXT_RENDERER as bA, AX_CONVERSATION_URL_ERRORS as bB, AX_CONVERSATION_USER_AVATAR_COMPONENT as bC, AX_CONVERSATION_USER_ERRORS as bD, AX_CONVERSATION_VIDEO_CATALOG as bE, AX_CONVERSATION_VIDEO_PRESENTATION as bF, AX_CONVERSATION_VIDEO_RENDERER as bG, AX_CONVERSATION_VOICE_CATALOG as bH, AX_CONVERSATION_VOICE_PRESENTATION as bI, AX_CONVERSATION_VOICE_RENDERER as bJ, AX_DEFAULT_CONVERSATION_CONFIG as bK, abortPickerUploads as bL, applyAudioLocalPreview as bM, applyFileLocalPreview as bN, applyLocalPreview as bO, applyVideoLocalPreview as bP, applyVoiceLocalPreview as bQ, audioItemFromUpload as bR, bindMediaRendererContentState as bS, buildMediaGalleryTiles as bT, canShowRendererContentError as bU, cleanupPickerUploads as bV, conversationAudioUtilities as bW, conversationFileUtilities as bX, conversationImageUtilities as bY, conversationVideoUtilities as bZ, conversationVoiceUtilities as b_, AX_CONVERSATION_ITEM_DIVIDER as ba, AX_CONVERSATION_ITEM_MARK_READ_ACTION as bb, AX_CONVERSATION_ITEM_MUTE_ACTION as bc, AX_CONVERSATION_ITEM_PIN_ACTION as bd, AX_CONVERSATION_JUMBO_EMOJI_MAX as be, AX_CONVERSATION_LOCATION_ERRORS as bf, AX_CONVERSATION_LOCATION_RENDERER as bg, AX_CONVERSATION_MESSAGE_DELETE_ACTION as bh, AX_CONVERSATION_MESSAGE_EDIT_ACTION as bi, AX_CONVERSATION_MESSAGE_ERRORS as bj, AX_CONVERSATION_MESSAGE_FORWARD_ACTION as bk, AX_CONVERSATION_MESSAGE_LIST_BACKGROUND_PRESETS as bl, AX_CONVERSATION_MESSAGE_REPLY_ACTION as bm, AX_CONVERSATION_MESSAGE_TYPE_FILE_TYPE as bn, AX_CONVERSATION_PEER_AVATAR_TYPES as bo, AX_CONVERSATION_REGISTRY_CONFIG as bp, AX_CONVERSATION_STICKER_API_KEY as bq, AX_CONVERSATION_STICKER_RENDERER as br, AX_CONVERSATION_SYSTEM_RENDERER as bs, AX_CONVERSATION_TAB_ALL as bt, AX_CONVERSATION_TAB_ARCHIVED as bu, AX_CONVERSATION_TAB_BOT as bv, AX_CONVERSATION_TAB_CHANNELS as bw, AX_CONVERSATION_TAB_GROUPS as bx, AX_CONVERSATION_TAB_PRIVATE as by, AX_CONVERSATION_TAB_UNREAD as bz, AXConversationAudioFileTypeProvider as c, mergeVoiceUploadResult as c$, countLoneEmojis as c0, createConversationAudioFileType as c1, createConversationFileFileType as c2, createConversationImageFileType as c3, createConversationVideoFileType as c4, createConversationVoiceFileType as c5, createLocalPreviewUrl as c6, createObjectUrl as c7, createPickerDragHandlers as c8, createPickerUploadItemId as c9, inferFileExtensionHintFromMessage as cA, isAttachmentListCategory as cB, isComposerAttachmentBannerEnabled as cC, isComposerTabEnabled as cD, isConversationReactionsEnabled as cE, isConversationRoomCreator as cF, isGenericPrivateConversationTitle as cG, isGridMediaCategory as cH, isGroupLikeConversation as cI, isJumboEmojiText as cJ, isJumboEmojiTextMessage as cK, isMessageDeliveryPending as cL, isMessageListThemeBackground as cM, isMessageVisibleAfterHistoryCutoff as cN, isNonPersistableMediaUrl as cO, isPickerItemReadyToSend as cP, isPlainChromeMessage as cQ, isSameMessageListBackground as cR, isUploadAborted as cS, limitFilesToCapacity as cT, listTextGraphemes as cU, mediaCopyText as cV, mergeAudioUploadResult as cW, mergeFileUploadResult as cX, mergeInfoPanelMessages as cY, mergeUploadResult as cZ, mergeVideoUploadResult as c_, createResolvedMediaUrlSignal as ca, deleteUploadedPickerMedia as cb, dismissComposerPickerHost as cc, ensureConversationFileCatalogRegistered as cd, fetchConversationMediaPage as ce, fileItemAsAudioMedia as cf, fileItemFromUpload as cg, filesFromClipboardEvent as ch, filterMessagesByMediaCategory as ci, filterSupplementalInfoPanelMessages as cj, findExistingPrivateConversation as ck, formatDuration as cl, formatErrorMessage as cm, formatFileByteSize as cn, formatFileSize as co, formatMediaDuration as cp, formatPickerValidationMessage as cq, getActiveComposerPickerPasteHandler as cr, getConversationMediaCategories as cs, getConversationProfileFields as ct, getErrorMessage as cu, getMessageAudioItems as cv, getMessageVideoItems as cw, getPickerCancelUploadLabel as cx, getPrivatePeerParticipant as cy, hasRegistryComponent as cz, AXConversationAudioPickerComponent as d, validateUserId as d$, mergeWithDefaults as d0, messageContainsLink as d1, normalizeAudioPayload as d2, normalizeConversationInboundFile as d3, normalizeFilePayload as d4, normalizeImagePayload as d5, normalizeMessageListBackgroundValue as d6, normalizeVideoPayload as d7, notifyMaxFilesCapacityExceeded as d8, notifyPickerValidationErrors as d9, resolveMessageListBackgroundRaw as dA, resolveMessageListBackgroundStyle as dB, resolveParticipantProfile as dC, resolvePersistableMediaUrl as dD, resolvePersistedThumbnailUrl as dE, resolvePrivatePeerParticipant as dF, resolvePrivatePeerUserId as dG, resolveUserAvatarDisplay as dH, resolveVideoThumbnailUrl as dI, revokeObjectUrl as dJ, revokePickerBlobPreviews as dK, sanitizeInput as dL, shouldUseUserAvatarForConversation as dM, sortUsersForForward as dN, syncPlaybackInfoBarBanner as dO, toUploaderReference$1 as dP, toUploaderReference as dQ, uploadPickerFile as dR, usesDefaultMessageListWallpaper as dS, validateConversationId as dT, validateEmail as dU, validateLatitude as dV, validateLongitude as dW, validateMessagePayload as dX, validateMessageText as dY, validateMessageType as dZ, validateUrl as d_, openWithFileType as da, pickDisplayMediaUrl as db, pickEarliestJoinedParticipant as dc, pickerItemToMediaReference as dd, pickerItemToUploadResult as de, probeAudioDuration as df, probeImageDimensions as dg, probeVideoMedia as dh, provideConversation as di, provideConversationComposerFileTypes as dj, provideConversationFileCatalog as dk, registerComposerPickerPasteHandler as dl, reportMediaLoadError as dm, resolveComposerAttachmentPresentation as dn, resolveComposerMaxFiles as dp, resolveConversationAvatarDisplay as dq, resolveConversationComposerTabs as dr, resolveConversationForViewer as ds, resolveConversationMessageFileType as dt, resolveConversationPeerParticipant as du, resolveConversationPeerUserId as dv, resolveConversationTitleForViewer as dw, resolveGalleryImageUrl as dx, resolveImageDisplayUrl as dy, resolveMessageChrome as dz, AXConversationAudioRendererComponent as e, validateUserIds as e0, videoItemFromUpload as e1, AXConversationAvatarComponent as f, AXConversationAvatarPickerComponent as g, AXConversationBaseRegistry as h, isValidPickerFileName as i, AXConversationComposerActionRegistry as j, AXConversationComposerComponent as k, AXConversationComposerFileTypesProvider as l, AXConversationComposerGenerationStateService as m, AXConversationComposerPopupComponent as n, AXConversationComposerService as o, AXConversationComposerTabRegistry as p, AXConversationContainerComponent as q, AXConversationContainerDirective as r, AXConversationDateUtilsService as s, AXConversationDeleteDialogComponent as t, AXConversationEmojiTabComponent as u, AXConversationErrorHandlerService as v, AXConversationFallbackRendererComponent as w, AXConversationFileAttachmentComponent as x, AXConversationFileFileTypeProvider as y, AXConversationFilePickerComponent as z };
19531
+ //# sourceMappingURL=acorex-components-conversation-acorex-components-conversation-BEDMf4vn.mjs.map