@leanix/components 0.2.248 → 0.2.251

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.
@@ -7,13 +7,13 @@ import { ComponentPortal, CdkPortal, PortalModule } from '@angular/cdk/portal';
7
7
  import * as i1 from '@angular/cdk/overlay';
8
8
  import { OverlayModule, CdkConnectedOverlay } from '@angular/cdk/overlay';
9
9
  import { __decorate } from 'tslib';
10
+ import { escape, trimEnd, sortBy, get, isEqual, toLower, some, padCharsStart, toString, isNaN as isNaN$1, toNumber, includes, last, findIndex, filter as filter$1, isObject, find, uniqueId } from 'lodash/fp';
10
11
  import * as i6 from 'rxjs';
11
12
  import { BehaviorSubject, timer, Subject, combineLatest, merge, concat, fromEvent, Observable, ReplaySubject, of } from 'rxjs';
12
13
  import { skipWhile, map, switchMap, startWith, pairwise, filter, take, debounceTime, skip, withLatestFrom, distinctUntilChanged, takeUntil, first, delay, mapTo, tap } from 'rxjs/operators';
13
14
  import * as i1$1 from '@ngx-translate/core';
14
15
  import { TranslatePipe, TranslateModule } from '@ngx-translate/core';
15
16
  import * as i1$2 from '@angular/platform-browser';
16
- import { trimEnd, sortBy, get, isEqual, toLower, some, padCharsStart, toString, isNaN as isNaN$1, toNumber, includes, last, findIndex, filter as filter$1, isObject, find, uniqueId } from 'lodash/fp';
17
17
  import Color from 'color';
18
18
  import { format, distanceInWords, startOfDay } from 'date-fns';
19
19
  import _, { curry } from 'lodash';
@@ -604,10 +604,21 @@ class EllipsisComponent {
604
604
  this.resizeObserverService = resizeObserverService;
605
605
  this.translateService = translateService;
606
606
  this.content = '';
607
+ /**
608
+ * Only set this to false if the content is not a user provided string
609
+ * or if you sanitize the provided content yourself.
610
+ */
611
+ this.escapeHtmlInContent = true;
607
612
  this.isShowingMore$ = new BehaviorSubject(false);
608
613
  this.destroyed$ = new Subject();
609
614
  }
610
615
  ngOnInit() {
616
+ this.sanitizedContent$ = this.content$.pipe(map((content) => {
617
+ if (this.escapeHtmlInContent && typeof content === 'string') {
618
+ return escape(content);
619
+ }
620
+ return content;
621
+ }));
611
622
  this.showMoreButtonLabel$ = this.isShowingMore$.pipe(switchMap((isShowingMore) => {
612
623
  const translationKey = isShowingMore ? 'common.showLess' : 'common.showMore';
613
624
  return this.translateService.get(translationKey);
@@ -676,7 +687,7 @@ class EllipsisComponent {
676
687
  }
677
688
  EllipsisComponent.DEFAULT_RESIZE_DEBOUNCE_MS = 500;
678
689
  EllipsisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: EllipsisComponent, deps: [{ token: LX_ELLIPSIS_DEBOUNCE_ON_RESIZE }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: ResizeObserverService }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
679
- EllipsisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: EllipsisComponent, selector: "lx-ellipsis", inputs: { content: "content" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span #contentEl [class.showMore]=\"isShowingMore$ | async\" class=\"content truncate lx-margin-right\" [innerHtml]=\"content\"></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], components: [{ type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "showSpinner"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
690
+ EllipsisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: EllipsisComponent, selector: "lx-ellipsis", inputs: { content: "content", escapeHtmlInContent: "escapeHtmlInContent" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], components: [{ type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "showSpinner"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
680
691
  __decorate([
681
692
  Observe('contentSpanEl')
682
693
  ], EllipsisComponent.prototype, "contentSpanEl$", void 0);
@@ -688,12 +699,14 @@ __decorate([
688
699
  ], EllipsisComponent.prototype, "content$", void 0);
689
700
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: EllipsisComponent, decorators: [{
690
701
  type: Component,
691
- args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span #contentEl [class.showMore]=\"isShowingMore$ | async\" class=\"content truncate lx-margin-right\" [innerHtml]=\"content\"></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
702
+ args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
692
703
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
693
704
  type: Inject,
694
705
  args: [LX_ELLIPSIS_DEBOUNCE_ON_RESIZE]
695
706
  }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: ResizeObserverService }, { type: i1$1.TranslateService }]; }, propDecorators: { content: [{
696
707
  type: Input
708
+ }], escapeHtmlInContent: [{
709
+ type: Input
697
710
  }], contentSpanEl$: [], contentSpanEl: [{
698
711
  type: ViewChild,
699
712
  args: ['contentEl']
@@ -1033,172 +1046,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1033
1046
  type: Input
1034
1047
  }] } });
1035
1048
 
1036
- class BrPipe {
1037
- transform(input, options = {}) {
1038
- if (input) {
1039
- if (options.isTrimEnd) {
1040
- input = trimEnd(input);
1041
- }
1042
- return input.replace(/[\n\r]/g, '<br/>');
1043
- }
1044
- return input;
1045
- }
1046
- }
1047
- BrPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1048
- BrPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, name: "lxBr" });
1049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, decorators: [{
1050
- type: Pipe,
1051
- args: [{
1052
- name: 'lxBr'
1053
- }]
1054
- }] });
1055
-
1056
- /**
1057
- * Compute the most eligible text color for a given background color (black or white), depending on the luminance of the
1058
- * background color. In case the provided color is undefined or invalid, white (#FFFFFF) is returned.
1059
- *
1060
- * @param colorHex Color string in hexadecimal encoding.
1061
- * @returns Equivalent contrast color in hexadecimal encoding.
1062
- */
1063
- function getContrastColor(colorHex) {
1064
- try {
1065
- const color = Color(colorHex || '#000');
1066
- // Check http://codepen.io/WebSeed/pen/pvgqEq
1067
- const a = 1 - (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255;
1068
- const d = a < 0.4 ? 0 : 255;
1069
- return Color({ r: d, g: d, b: d }).hex();
1070
- }
1071
- catch {
1072
- return '#FFFFFF';
1073
- }
1074
- }
1075
- function shorthandHexHandle(hex) {
1076
- const shorthandRegex = /^(#)([a-f\d])([a-f\d])([a-f\d])$/i;
1077
- const shorthand = hex.match(shorthandRegex);
1078
- if (shorthand) {
1079
- const convertedHex = shorthand[1] + shorthand[2] + shorthand[2] + shorthand[3] + shorthand[3] + shorthand[4] + shorthand[4];
1080
- return convertedHex;
1081
- }
1082
- else {
1083
- return hex;
1084
- }
1085
- }
1086
- function isValidHexColor(color) {
1087
- return /^#[0-9A-F]{6}$/i.test(color);
1088
- }
1089
-
1090
- class ContrastColorPipe {
1091
- transform(color) {
1092
- if (color) {
1093
- return isValidHexColor(shorthandHexHandle(color)) ? getContrastColor(color) : '';
1094
- }
1095
- return '';
1096
- }
1097
- }
1098
- ContrastColorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1099
- ContrastColorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, name: "lxContrastColor" });
1100
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, decorators: [{
1101
- type: Pipe,
1102
- args: [{
1103
- name: 'lxContrastColor'
1104
- }]
1105
- }] });
1106
-
1107
- const DATE_FORMATS = new InjectionToken('DATE_FORMATS', {
1108
- providedIn: 'root',
1109
- factory: () => ({
1110
- getDateFormat: () => 'YYYY-MM-DD',
1111
- getDateTimeFormat: () => 'YYYY-MM-DD HH:mm',
1112
- getDateTimeFormatWithSeconds: () => 'YYYY-MM-DD HH:mm:ss'
1113
- })
1114
- });
1115
- const DATE_FN_LOCALE = new InjectionToken('DATE_FN_LOCALE');
1116
- const LOCALE_FN = new InjectionToken('LOCALE_FN');
1117
- const GLOBAL_TRANSLATION_OPTIONS = new InjectionToken('GLOBAL_TRANSLATION_OPTIONS');
1118
-
1119
- class CustomDatePipe {
1120
- constructor(getDateFnLocale) {
1121
- this.getDateFnLocale = getDateFnLocale;
1122
- }
1123
- transform(value, f) {
1124
- const locale = this.getDateFnLocale ? this.getDateFnLocale() : null;
1125
- return value ? format(value, f, { locale }) : '';
1126
- }
1127
- }
1128
- CustomDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, deps: [{ token: DATE_FN_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
1129
- CustomDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, name: "lxDate" });
1130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, decorators: [{
1131
- type: Pipe,
1132
- args: [{
1133
- name: 'lxDate'
1134
- }]
1135
- }], ctorParameters: function () { return [{ type: Function, decorators: [{
1136
- type: Optional
1137
- }, {
1138
- type: Inject,
1139
- args: [DATE_FN_LOCALE]
1140
- }] }]; } });
1141
-
1142
- class HighlightRangePipe {
1143
- transform(text, offset = 0, length = 0) {
1144
- if (!text || offset < 0 || length < 0 || offset >= text?.length || offset + length > text?.length) {
1145
- return '';
1146
- }
1147
- const highlightedPart = text.slice(offset, offset + length);
1148
- return text.slice(0, offset) + (highlightedPart.length !== 0 ? this.highlight(highlightedPart) : '') + text.slice(offset + length);
1149
- }
1150
- highlight(text) {
1151
- return `<span class="termHighlight">${text}</span>`;
1152
- }
1153
- }
1154
- HighlightRangePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1155
- HighlightRangePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, name: "lxHighlightRange" });
1156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, decorators: [{
1157
- type: Pipe,
1158
- args: [{ name: 'lxHighlightRange' }]
1159
- }] });
1160
-
1161
- /**
1162
- * These characters are treated as seperators by
1163
- * elasticsearch and split the input into search tokens
1164
- * which are used to find matches.
1165
- */
1166
- const STANDARD_TOKENIZER_SEPERATORS = /[^a-zA-Z\d\s]/g;
1167
- class HighlightTermPipe {
1168
- transform(text, search) {
1169
- if (search && text) {
1170
- let pattern = search
1171
- .replace(STANDARD_TOKENIZER_SEPERATORS, ' ')
1172
- // replace special chars for a backslash for RegExp
1173
- .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
1174
- pattern = pattern
1175
- .split(' ')
1176
- .filter((t) => {
1177
- return t.length > 0;
1178
- })
1179
- .join('|');
1180
- const regex = new RegExp(pattern, 'gi');
1181
- text = _.escape(text);
1182
- return text.replace(regex, (match) => `<span class="termHighlight">${match}</span>`); // add highlighting to matched regex pattern
1183
- }
1184
- else {
1185
- return text;
1186
- }
1187
- }
1188
- }
1189
- HighlightTermPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1190
- HighlightTermPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, name: "lxHighlightTerm" });
1191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, decorators: [{
1192
- type: Pipe,
1193
- args: [{ name: 'lxHighlightTerm' }]
1194
- }] });
1195
-
1196
1049
  /**
1197
1050
  * This pipe transforms...
1198
1051
  * - "raw" http(s) links
1199
1052
  * - markdown link syntax
1200
1053
  * ... into clickable anchor elements.
1201
1054
  *
1055
+ * The characters "<" and ">" are escaped with their HTML entities &lt; and &gt;.
1056
+ *
1202
1057
  * You have an user interface where you don't want clickable links but also
1203
1058
  * don't want users to see the "ugly" markdown link syntax?
1204
1059
  * -> Use the 'lxUnlikify' pipe to replace markdown link syntax with just the link name
@@ -1206,7 +1061,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1206
1061
  class LxLinkifyPipe {
1207
1062
  transform(text) {
1208
1063
  if (text && typeof text === 'string') {
1209
- const textWithRawLinks = this.wrapRawHttpLinksWithAnchorTags(text);
1064
+ const escapedText = this.escapeHtmlInUserProvidedString(text);
1065
+ const textWithRawLinks = this.wrapRawHttpLinksWithAnchorTags(escapedText);
1210
1066
  const textWithRawAndNamedLinks = this.turnMarkdownStyleLinksIntoAnchorTags(textWithRawLinks);
1211
1067
  return textWithRawAndNamedLinks;
1212
1068
  }
@@ -1285,6 +1141,17 @@ class LxLinkifyPipe {
1285
1141
  }
1286
1142
  return matches;
1287
1143
  }
1144
+ /**
1145
+ * We assume that lxLinkify is exclusively used on user provided strings.
1146
+ * This is why we want to escape any other HTML tags that are already present in the string.
1147
+ * The logic implemented here has been used with no issues for three years in our Fact Sheet comments. See https://github.com/gregjacobs/Autolinker.js/pull/313
1148
+ *
1149
+ * When using lxLinkify in conjunction with other pipes that add HTML, make sure to use lxLinkify first,
1150
+ * so that it doesn't escape the HTML of any previous pipes.
1151
+ */
1152
+ escapeHtmlInUserProvidedString(input) {
1153
+ return input.replace(/<|>/gi, (match) => '&' + (match === '>' ? 'g' : 'l') + 't;');
1154
+ }
1288
1155
  }
1289
1156
  /**
1290
1157
  * This is not the "one URL regex to rule them all", but a more realistic one which should work
@@ -1366,6 +1233,166 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1366
1233
  args: [{ name: 'lxUnlinkify' }]
1367
1234
  }] });
1368
1235
 
1236
+ class BrPipe {
1237
+ transform(input, options = {}) {
1238
+ if (input) {
1239
+ if (options.isTrimEnd) {
1240
+ input = trimEnd(input);
1241
+ }
1242
+ return input.replace(/[\n\r]/g, '<br/>');
1243
+ }
1244
+ return input;
1245
+ }
1246
+ }
1247
+ BrPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1248
+ BrPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, name: "lxBr" });
1249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, decorators: [{
1250
+ type: Pipe,
1251
+ args: [{
1252
+ name: 'lxBr'
1253
+ }]
1254
+ }] });
1255
+
1256
+ /**
1257
+ * Compute the most eligible text color for a given background color (black or white), depending on the luminance of the
1258
+ * background color. In case the provided color is undefined or invalid, white (#FFFFFF) is returned.
1259
+ *
1260
+ * @param colorHex Color string in hexadecimal encoding.
1261
+ * @returns Equivalent contrast color in hexadecimal encoding.
1262
+ */
1263
+ function getContrastColor(colorHex) {
1264
+ try {
1265
+ const color = Color(colorHex || '#000');
1266
+ // Check http://codepen.io/WebSeed/pen/pvgqEq
1267
+ const a = 1 - (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255;
1268
+ const d = a < 0.4 ? 0 : 255;
1269
+ return Color({ r: d, g: d, b: d }).hex();
1270
+ }
1271
+ catch {
1272
+ return '#FFFFFF';
1273
+ }
1274
+ }
1275
+ function shorthandHexHandle(hex) {
1276
+ const shorthandRegex = /^(#)([a-f\d])([a-f\d])([a-f\d])$/i;
1277
+ const shorthand = hex.match(shorthandRegex);
1278
+ if (shorthand) {
1279
+ const convertedHex = shorthand[1] + shorthand[2] + shorthand[2] + shorthand[3] + shorthand[3] + shorthand[4] + shorthand[4];
1280
+ return convertedHex;
1281
+ }
1282
+ else {
1283
+ return hex;
1284
+ }
1285
+ }
1286
+ function isValidHexColor(color) {
1287
+ return /^#[0-9A-F]{6}$/i.test(color);
1288
+ }
1289
+
1290
+ class ContrastColorPipe {
1291
+ transform(color) {
1292
+ if (color) {
1293
+ return isValidHexColor(shorthandHexHandle(color)) ? getContrastColor(color) : '';
1294
+ }
1295
+ return '';
1296
+ }
1297
+ }
1298
+ ContrastColorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1299
+ ContrastColorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, name: "lxContrastColor" });
1300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, decorators: [{
1301
+ type: Pipe,
1302
+ args: [{
1303
+ name: 'lxContrastColor'
1304
+ }]
1305
+ }] });
1306
+
1307
+ const DATE_FORMATS = new InjectionToken('DATE_FORMATS', {
1308
+ providedIn: 'root',
1309
+ factory: () => ({
1310
+ getDateFormat: () => 'YYYY-MM-DD',
1311
+ getDateTimeFormat: () => 'YYYY-MM-DD HH:mm',
1312
+ getDateTimeFormatWithSeconds: () => 'YYYY-MM-DD HH:mm:ss'
1313
+ })
1314
+ });
1315
+ const DATE_FN_LOCALE = new InjectionToken('DATE_FN_LOCALE');
1316
+ const LOCALE_FN = new InjectionToken('LOCALE_FN');
1317
+ const GLOBAL_TRANSLATION_OPTIONS = new InjectionToken('GLOBAL_TRANSLATION_OPTIONS');
1318
+
1319
+ class CustomDatePipe {
1320
+ constructor(getDateFnLocale) {
1321
+ this.getDateFnLocale = getDateFnLocale;
1322
+ }
1323
+ transform(value, f) {
1324
+ const locale = this.getDateFnLocale ? this.getDateFnLocale() : null;
1325
+ return value ? format(value, f, { locale }) : '';
1326
+ }
1327
+ }
1328
+ CustomDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, deps: [{ token: DATE_FN_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
1329
+ CustomDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, name: "lxDate" });
1330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, decorators: [{
1331
+ type: Pipe,
1332
+ args: [{
1333
+ name: 'lxDate'
1334
+ }]
1335
+ }], ctorParameters: function () { return [{ type: Function, decorators: [{
1336
+ type: Optional
1337
+ }, {
1338
+ type: Inject,
1339
+ args: [DATE_FN_LOCALE]
1340
+ }] }]; } });
1341
+
1342
+ class HighlightRangePipe {
1343
+ transform(text, offset = 0, length = 0) {
1344
+ if (!text || offset < 0 || length < 0 || offset >= text?.length || offset + length > text?.length) {
1345
+ return '';
1346
+ }
1347
+ const highlightedPart = text.slice(offset, offset + length);
1348
+ return text.slice(0, offset) + (highlightedPart.length !== 0 ? this.highlight(highlightedPart) : '') + text.slice(offset + length);
1349
+ }
1350
+ highlight(text) {
1351
+ return `<span class="termHighlight">${text}</span>`;
1352
+ }
1353
+ }
1354
+ HighlightRangePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1355
+ HighlightRangePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, name: "lxHighlightRange" });
1356
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, decorators: [{
1357
+ type: Pipe,
1358
+ args: [{ name: 'lxHighlightRange' }]
1359
+ }] });
1360
+
1361
+ /**
1362
+ * These characters are treated as seperators by
1363
+ * elasticsearch and split the input into search tokens
1364
+ * which are used to find matches.
1365
+ */
1366
+ const STANDARD_TOKENIZER_SEPERATORS = /[^a-zA-Z\d\s]/g;
1367
+ class HighlightTermPipe {
1368
+ transform(text, search) {
1369
+ if (search && text) {
1370
+ let pattern = search
1371
+ .replace(STANDARD_TOKENIZER_SEPERATORS, ' ')
1372
+ // replace special chars for a backslash for RegExp
1373
+ .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
1374
+ pattern = pattern
1375
+ .split(' ')
1376
+ .filter((t) => {
1377
+ return t.length > 0;
1378
+ })
1379
+ .join('|');
1380
+ const regex = new RegExp(pattern, 'gi');
1381
+ text = _.escape(text);
1382
+ return text.replace(regex, (match) => `<span class="termHighlight">${match}</span>`); // add highlighting to matched regex pattern
1383
+ }
1384
+ else {
1385
+ return text;
1386
+ }
1387
+ }
1388
+ }
1389
+ HighlightTermPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1390
+ HighlightTermPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, name: "lxHighlightTerm" });
1391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, decorators: [{
1392
+ type: Pipe,
1393
+ args: [{ name: 'lxHighlightTerm' }]
1394
+ }] });
1395
+
1369
1396
  function isUuid(s) {
1370
1397
  const uuidRegEx = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
1371
1398
  return uuidRegEx.test(s);
@@ -6099,6 +6126,7 @@ class PopoverComponent {
6099
6126
  constructor() {
6100
6127
  this.noMargin = false;
6101
6128
  this.allowOverflow = false;
6129
+ this.autoFocus = false;
6102
6130
  /**
6103
6131
  * If you have a popover, that should usually be displayed above or below its anchor,
6104
6132
  * and this anchor is in a scrollable container, you should set this to true.
@@ -6207,10 +6235,10 @@ class PopoverComponent {
6207
6235
  }
6208
6236
  }
6209
6237
  PopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6210
- PopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: PopoverComponent, selector: "lx-popover", inputs: { trigger: "trigger", horizontalAlign: "horizontalAlign", verticalAlign: "verticalAlign", noMargin: "noMargin", allowOverflow: "allowOverflow", adaptMarginsForViewportAlignChange: "adaptMarginsForViewportAlignChange" }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "explicitContent", first: true, predicate: PopoverContentDirective, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "satPopover", first: true, predicate: SatPopover, descendants: true, static: true }, { propertyName: "implicitContent", first: true, predicate: ["implicitContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"false\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"], components: [{ type: i1$6.SatPopover, selector: "sat-popover", inputs: ["anchor", "horizontalAlign", "xAlign", "verticalAlign", "yAlign", "forceAlignment", "lockAlignment", "autoFocus", "restoreFocus", "scrollStrategy", "hasBackdrop", "interactiveClose", "openTransition", "closeTransition", "openAnimationStartAtScale", "closeAnimationEndAtScale", "backdropClass", "panelClass"], outputs: ["opened", "closed", "afterOpen", "afterClose", "backdropClicked", "overlayKeydown"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
6238
+ PopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: PopoverComponent, selector: "lx-popover", inputs: { trigger: "trigger", horizontalAlign: "horizontalAlign", verticalAlign: "verticalAlign", noMargin: "noMargin", allowOverflow: "allowOverflow", autoFocus: "autoFocus", adaptMarginsForViewportAlignChange: "adaptMarginsForViewportAlignChange" }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "explicitContent", first: true, predicate: PopoverContentDirective, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "satPopover", first: true, predicate: SatPopover, descendants: true, static: true }, { propertyName: "implicitContent", first: true, predicate: ["implicitContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"autoFocus\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n (keydown.escape)=\"$event.stopPropagation(); trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"], components: [{ type: i1$6.SatPopover, selector: "sat-popover", inputs: ["anchor", "horizontalAlign", "xAlign", "verticalAlign", "yAlign", "forceAlignment", "lockAlignment", "autoFocus", "restoreFocus", "scrollStrategy", "hasBackdrop", "interactiveClose", "openTransition", "closeTransition", "openAnimationStartAtScale", "closeAnimationEndAtScale", "backdropClass", "panelClass"], outputs: ["opened", "closed", "afterOpen", "afterClose", "backdropClicked", "overlayKeydown"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
6211
6239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PopoverComponent, decorators: [{
6212
6240
  type: Component,
6213
- args: [{ selector: 'lx-popover', template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"false\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"] }]
6241
+ args: [{ selector: 'lx-popover', template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"autoFocus\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n (keydown.escape)=\"$event.stopPropagation(); trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"] }]
6214
6242
  }], propDecorators: { trigger: [{
6215
6243
  type: Input
6216
6244
  }], horizontalAlign: [{
@@ -6221,6 +6249,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
6221
6249
  type: Input
6222
6250
  }], allowOverflow: [{
6223
6251
  type: Input
6252
+ }], autoFocus: [{
6253
+ type: Input
6224
6254
  }], adaptMarginsForViewportAlignChange: [{
6225
6255
  type: Input
6226
6256
  }], opened: [{