@banta/sdk 4.7.12 → 4.7.14

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.
@@ -2,8 +2,9 @@ import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
2
2
  import { publish, take } from 'rxjs/operators';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Component, Input, ViewChild, Pipe, Inject, Optional, Output, HostBinding, NgModule, ViewChildren, Directive, TemplateRef, ContentChild, Injectable as Injectable$1 } from '@angular/core';
5
- import * as i1 from 'projects/sdk/src/lib/common/timer-pool.service';
6
- import { TimerPool as TimerPool$1 } from 'projects/sdk/src/lib/common/timer-pool.service';
5
+ import { __decorate } from 'tslib';
6
+ import * as i1$2 from '@banta/common';
7
+ import { Injectable, CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
7
8
  import * as i2 from '@angular/common';
8
9
  import { CommonModule } from '@angular/common';
9
10
  import * as i2$1 from '@angular/material/icon';
@@ -11,22 +12,19 @@ import { MatIconModule } from '@angular/material/icon';
11
12
  import * as marked from 'marked';
12
13
  import createDOMPurify from 'dompurify';
13
14
  import twemoji$1 from 'twemoji';
14
- import * as i1$1 from '@angular/platform-browser';
15
+ import * as i1 from '@angular/platform-browser';
15
16
  import * as i3 from '@angular/cdk/bidi';
16
17
  import * as i4 from '@angular/material/progress-spinner';
17
18
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
18
19
  import * as i6 from '@angular/material/button';
19
20
  import { MatButtonModule } from '@angular/material/button';
20
- import { __decorate } from 'tslib';
21
- import * as i1$3 from '@banta/common';
22
- import { Injectable, CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
23
21
  import * as i4$1 from '@angular/forms';
24
22
  import { FormsModule } from '@angular/forms';
25
23
  import * as i6$1 from '@angular/material/form-field';
26
24
  import { MatFormFieldModule } from '@angular/material/form-field';
27
25
  import * as i7 from '@angular/material/input';
28
26
  import { MatInputModule } from '@angular/material/input';
29
- import * as i1$2 from '@angular/cdk/overlay';
27
+ import * as i1$1 from '@angular/cdk/overlay';
30
28
  import { OverlayModule } from '@angular/cdk/overlay';
31
29
  import * as i4$2 from '@angular/cdk/portal';
32
30
  import { PortalModule } from '@angular/cdk/portal';
@@ -58,6 +56,86 @@ function lazyConnection(options) {
58
56
  return obs.pipe(publish()).refCount();
59
57
  }
60
58
 
59
+ /**
60
+ * Provides a way to hook in to a shared set of timers, instead of creating a timer per instance.
61
+ * This is very useful for cases where the update is not extremely time-sensitive, but happens at scale.
62
+ * The principal use case is the TimestampComponent. When several hundred (or several thousand) comments are
63
+ * being displayed, we do not want to trigger thousands of independent relative timestamp updates, because over
64
+ * time the updates will saturate the CPU since they don't perfectly align.
65
+ */
66
+ let TimerPool = class TimerPool {
67
+ constructor() {
68
+ this.subscriptions = new Map();
69
+ this.newSubscriptions = new Map();
70
+ this.removedSubscriptions = new Map();
71
+ }
72
+ addTimer(interval, callback) {
73
+ if (interval <= 0) {
74
+ console.warn(`Refusing to set timer with interval of ${interval}!`);
75
+ return () => { };
76
+ }
77
+ let state;
78
+ let sizeWas = this.subscriptions.size;
79
+ if (!this.subscriptions.has(interval)) {
80
+ state = { subscribers: [] };
81
+ state.handle = setInterval(() => {
82
+ console.debug(`[Banta/TimerPool] Notifying ${state.subscribers.length} subs [${interval}ms]`);
83
+ state.subscribers.forEach(sub => sub());
84
+ }, interval);
85
+ this.subscriptions.set(interval, state);
86
+ }
87
+ else {
88
+ state = this.subscriptions.get(interval);
89
+ }
90
+ state.subscribers.push(callback);
91
+ // Debug information //////////////////////////
92
+ //
93
+ if (!this.newSubscriptions.has(interval))
94
+ this.newSubscriptions.set(interval, 0);
95
+ this.newSubscriptions.set(interval, (this.newSubscriptions.get(interval) ?? 0) + 1);
96
+ clearTimeout(this.newSubscriptionsNotice);
97
+ this.newSubscriptionsNotice = setTimeout(() => {
98
+ for (let [interval, count] of this.newSubscriptions) {
99
+ console.debug(`[Banta/TimerPool] ${count} new subscriptions to ${interval}ms [${state.subscribers.length} total]`);
100
+ }
101
+ this.newSubscriptions.clear();
102
+ });
103
+ //
104
+ ///////////////////////////////////////////////
105
+ if (sizeWas === 0) {
106
+ console.debug(`[Banta/TimerPool] No longer idle.`);
107
+ }
108
+ // Unsubscribe function
109
+ return () => {
110
+ let state = this.subscriptions.get(interval);
111
+ let index = state.subscribers.indexOf(callback);
112
+ if (index >= 0)
113
+ state.subscribers.splice(index, 1);
114
+ if (state.subscribers.length === 0) {
115
+ clearInterval(state.handle);
116
+ this.subscriptions.delete(interval);
117
+ }
118
+ if (!this.removedSubscriptions.has(interval))
119
+ this.removedSubscriptions.set(interval, 0);
120
+ this.removedSubscriptions.set(interval, (this.removedSubscriptions.get(interval) ?? 0) + 1);
121
+ // Debug information ////////////////////////////////////////////////////////////////////
122
+ clearTimeout(this.removedSubscriptionsNotice);
123
+ this.removedSubscriptionsNotice = setTimeout(() => {
124
+ for (let [interval, count] of this.removedSubscriptions) {
125
+ let state = this.subscriptions.get(interval);
126
+ console.debug(`[Banta/TimerPool] ${count} unsubscribed from ${interval}ms [${state?.subscribers?.length ?? 0} remain]`);
127
+ }
128
+ if (this.subscriptions.size === 0)
129
+ console.debug(`[Banta/TimerPool] All subscriptions have been removed. Now idle.`);
130
+ this.removedSubscriptions.clear();
131
+ });
132
+ };
133
+ }
134
+ };
135
+ TimerPool = __decorate([
136
+ Injectable()
137
+ ], TimerPool);
138
+
61
139
  class TimestampComponent {
62
140
  constructor(timerPool) {
63
141
  this.timerPool = timerPool;
@@ -154,7 +232,7 @@ class TimestampComponent {
154
232
  }
155
233
  }
156
234
  }
157
- TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [{ token: i1.TimerPool }], target: i0.ɵɵFactoryTarget.Component });
235
+ TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [{ token: TimerPool }], target: i0.ɵɵFactoryTarget.Component });
158
236
  TimestampComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: TimestampComponent, selector: "banta-timestamp", inputs: { value: "value" }, ngImport: i0, template: `
159
237
  <span *ngIf="showAbsolute" [title]="value | date : 'short'">
160
238
  {{value | date : 'shortDate'}}
@@ -173,7 +251,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
173
251
  {{relative}}
174
252
  </span>
175
253
  ` }]
176
- }], ctorParameters: function () { return [{ type: i1.TimerPool }]; }, propDecorators: { value: [{
254
+ }], ctorParameters: function () { return [{ type: TimerPool }]; }, propDecorators: { value: [{
177
255
  type: Input
178
256
  }] } });
179
257
 
@@ -275,14 +353,14 @@ class BantaMarkdownToHtmlPipe {
275
353
  }));
276
354
  }
277
355
  }
278
- BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
356
+ BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
279
357
  BantaMarkdownToHtmlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, name: "markdownToHtml" });
280
358
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, decorators: [{
281
359
  type: Pipe,
282
360
  args: [{
283
361
  name: 'markdownToHtml'
284
362
  }]
285
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
363
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
286
364
  type: Inject,
287
365
  args: [BANTA_SDK_OPTIONS]
288
366
  }, {
@@ -299,14 +377,14 @@ class BantaTrustResourceUrlPipe {
299
377
  return this.sanitizer.bypassSecurityTrustResourceUrl(value);
300
378
  }
301
379
  }
302
- BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
380
+ BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
303
381
  BantaTrustResourceUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, name: "trustResourceUrl" });
304
382
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, decorators: [{
305
383
  type: Pipe,
306
384
  args: [{
307
385
  name: 'trustResourceUrl'
308
386
  }]
309
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
387
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
310
388
 
311
389
  class BantaMentionLinkerPipe {
312
390
  transform(value, links) {
@@ -513,86 +591,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
513
591
  type: Output
514
592
  }] } });
515
593
 
516
- /**
517
- * Provides a way to hook in to a shared set of timers, instead of creating a timer per instance.
518
- * This is very useful for cases where the update is not extremely time-sensitive, but happens at scale.
519
- * The principal use case is the TimestampComponent. When several hundred (or several thousand) comments are
520
- * being displayed, we do not want to trigger thousands of independent relative timestamp updates, because over
521
- * time the updates will saturate the CPU since they don't perfectly align.
522
- */
523
- let TimerPool = class TimerPool {
524
- constructor() {
525
- this.subscriptions = new Map();
526
- this.newSubscriptions = new Map();
527
- this.removedSubscriptions = new Map();
528
- }
529
- addTimer(interval, callback) {
530
- if (interval <= 0) {
531
- console.warn(`Refusing to set timer with interval of ${interval}!`);
532
- return () => { };
533
- }
534
- let state;
535
- let sizeWas = this.subscriptions.size;
536
- if (!this.subscriptions.has(interval)) {
537
- state = { subscribers: [] };
538
- state.handle = setInterval(() => {
539
- console.debug(`[Banta/TimerPool] Notifying ${state.subscribers.length} subs [${interval}ms]`);
540
- state.subscribers.forEach(sub => sub());
541
- }, interval);
542
- this.subscriptions.set(interval, state);
543
- }
544
- else {
545
- state = this.subscriptions.get(interval);
546
- }
547
- state.subscribers.push(callback);
548
- // Debug information //////////////////////////
549
- //
550
- if (!this.newSubscriptions.has(interval))
551
- this.newSubscriptions.set(interval, 0);
552
- this.newSubscriptions.set(interval, (this.newSubscriptions.get(interval) ?? 0) + 1);
553
- clearTimeout(this.newSubscriptionsNotice);
554
- this.newSubscriptionsNotice = setTimeout(() => {
555
- for (let [interval, count] of this.newSubscriptions) {
556
- console.debug(`[Banta/TimerPool] ${count} new subscriptions to ${interval}ms [${state.subscribers.length} total]`);
557
- }
558
- this.newSubscriptions.clear();
559
- });
560
- //
561
- ///////////////////////////////////////////////
562
- if (sizeWas === 0) {
563
- console.debug(`[Banta/TimerPool] No longer idle.`);
564
- }
565
- // Unsubscribe function
566
- return () => {
567
- let state = this.subscriptions.get(interval);
568
- let index = state.subscribers.indexOf(callback);
569
- if (index >= 0)
570
- state.subscribers.splice(index, 1);
571
- if (state.subscribers.length === 0) {
572
- clearInterval(state.handle);
573
- this.subscriptions.delete(interval);
574
- }
575
- if (!this.removedSubscriptions.has(interval))
576
- this.removedSubscriptions.set(interval, 0);
577
- this.removedSubscriptions.set(interval, (this.removedSubscriptions.get(interval) ?? 0) + 1);
578
- // Debug information ////////////////////////////////////////////////////////////////////
579
- clearTimeout(this.removedSubscriptionsNotice);
580
- this.removedSubscriptionsNotice = setTimeout(() => {
581
- for (let [interval, count] of this.removedSubscriptions) {
582
- let state = this.subscriptions.get(interval);
583
- console.debug(`[Banta/TimerPool] ${count} unsubscribed from ${interval}ms [${state?.subscribers?.length ?? 0} remain]`);
584
- }
585
- if (this.subscriptions.size === 0)
586
- console.debug(`[Banta/TimerPool] All subscriptions have been removed. Now idle.`);
587
- this.removedSubscriptions.clear();
588
- });
589
- };
590
- }
591
- };
592
- TimerPool = __decorate([
593
- Injectable()
594
- ], TimerPool);
595
-
596
594
  const COMPONENTS$3 = [
597
595
  TimestampComponent,
598
596
  LightboxComponent,
@@ -607,7 +605,7 @@ class BantaCommonModule {
607
605
  return {
608
606
  ngModule: BantaCommonModule,
609
607
  providers: [
610
- TimerPool$1
608
+ TimerPool
611
609
  ]
612
610
  };
613
611
  }
@@ -7227,12 +7225,12 @@ class EmojiSelectorPanelComponent {
7227
7225
  this.categories = this.pairs(cats).map(pair => pair[1]);
7228
7226
  }
7229
7227
  }
7230
- EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7228
+ EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7231
7229
  EmojiSelectorPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: { selected: "selected" }, ngImport: i0, template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
7232
7230
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, decorators: [{
7233
7231
  type: Component,
7234
7232
  args: [{ selector: 'emoji-selector-panel', template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"] }]
7235
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
7233
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
7236
7234
  type: Inject,
7237
7235
  args: [BANTA_SDK_OPTIONS]
7238
7236
  }, {
@@ -7306,7 +7304,7 @@ class EmojiSelectorButtonComponent {
7306
7304
  this.overlayRef.attach(this.selectorPanelTemplate);
7307
7305
  }
7308
7306
  }
7309
- EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$2.Overlay }], target: i0.ɵɵFactoryTarget.Component });
7307
+ EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component });
7310
7308
  EmojiSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: { overlayX: "overlayX", overlayY: "overlayY", originX: "originX", originY: "originY" }, outputs: { selected: "selected" }, viewQueries: [{ propertyName: "selectorPanelTemplate", first: true, predicate: ["selectorPanelTemplate"], descendants: true }], ngImport: i0, template: `
7311
7309
  <button #button type="button" mat-icon-button (click)="show()">
7312
7310
  <mat-icon>emoji_emotions</mat-icon>
@@ -7331,7 +7329,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
7331
7329
  ></emoji-selector-panel>
7332
7330
  </ng-template>
7333
7331
  `, styles: [":host{display:block;position:relative}button{color:#666}\n"] }]
7334
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$2.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
7332
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$1.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
7335
7333
  type: ViewChild,
7336
7334
  args: ['selectorPanelTemplate']
7337
7335
  }], selected: [{
@@ -8046,12 +8044,12 @@ class AttachmentButtonComponent {
8046
8044
  }
8047
8045
  }
8048
8046
  }
8049
- AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$3.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
8047
+ AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$2.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
8050
8048
  AttachmentButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: AttachmentButtonComponent, selector: "banta-attachment-button", outputs: { addedAttachment: "addedAttachment", attachmentError: "attachmentError" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileUpload"], descendants: true }], ngImport: i0, template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8051
8049
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
8052
8050
  type: Component,
8053
8051
  args: [{ selector: 'banta-attachment-button', template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"] }]
8054
- }], ctorParameters: function () { return [{ type: i1$3.CDNProvider }]; }, propDecorators: { fileInput: [{
8052
+ }], ctorParameters: function () { return [{ type: i1$2.CDNProvider }]; }, propDecorators: { fileInput: [{
8055
8053
  type: ViewChild,
8056
8054
  args: ['fileUpload', { static: false }]
8057
8055
  }], addedAttachment: [{