@sumaris-net/ngx-components 18.16.5 → 18.16.7

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.
Files changed (31) hide show
  1. package/doc/changelog.md +8 -0
  2. package/esm2022/public_api.mjs +3 -1
  3. package/esm2022/src/app/core/graphql/graphql.service.mjs +16 -30
  4. package/esm2022/src/app/core/services/account.service.mjs +3 -3
  5. package/esm2022/src/app/core/services/local-settings.service.mjs +3 -3
  6. package/esm2022/src/app/core/services/network.service.mjs +100 -32
  7. package/esm2022/src/app/shared/base64.utils.mjs +59 -0
  8. package/esm2022/src/app/shared/functions.mjs +1 -10
  9. package/esm2022/src/app/shared/html.utils.mjs +35 -0
  10. package/esm2022/src/app/shared/pipes/html.pipes.mjs +36 -3
  11. package/esm2022/src/app/shared/pipes/pipes.module.mjs +5 -2
  12. package/esm2022/src/app/social/feed/feed.component.mjs +13 -11
  13. package/esm2022/src/app/social/feed/feed.model.mjs +4 -12
  14. package/esm2022/src/app/social/feed/feed.module.mjs +5 -4
  15. package/esm2022/src/app/social/feed/feed.service.mjs +2 -2
  16. package/esm2022/src/environments/environment.mjs +2 -1
  17. package/fesm2022/sumaris-net.ngx-components.mjs +258 -92
  18. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  19. package/package.json +1 -1
  20. package/public_api.d.ts +2 -0
  21. package/src/app/core/graphql/graphql.service.d.ts +5 -9
  22. package/src/app/core/services/network.service.d.ts +28 -10
  23. package/src/app/shared/base64.utils.d.ts +7 -0
  24. package/src/app/shared/functions.d.ts +0 -1
  25. package/src/app/shared/html.utils.d.ts +17 -0
  26. package/src/app/shared/inputs.d.ts +1 -1
  27. package/src/app/shared/pipes/html.pipes.d.ts +28 -0
  28. package/src/app/shared/pipes/pipes.module.d.ts +1 -1
  29. package/src/app/social/feed/feed.model.d.ts +2 -3
  30. package/src/app/social/feed/feed.module.d.ts +2 -1
  31. package/src/assets/manifest.json +1 -1
@@ -944,15 +944,6 @@ function intersectArrays(values) {
944
944
  // Utilise la méthode reduce pour obtenir l'intersection des tableaux
945
945
  return values.reduce((acc, curr) => acc.filter((x) => curr.includes(x)), values[0].slice());
946
946
  }
947
- function noHtml(value) {
948
- if (value && typeof value === 'string') {
949
- // Use regular expression to remove all HTML tags
950
- return value.replace(/<[^>]*>.*?<\/[^>]*>|<[^>]+>/g, '');
951
- }
952
- else {
953
- return value;
954
- }
955
- }
956
947
  /**
957
948
  * Interpolates a string by replacing placeholders with corresponding values from the provided object.
958
949
  *
@@ -5534,7 +5525,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5534
5525
  }] });
5535
5526
 
5536
5527
  /**
5537
- * Remove all HTML tags, from an input string
5528
+ * Removes all HTML tags from a given string.
5529
+ *
5530
+ * @param {string} value - The input string potentially containing HTML tags.
5531
+ * @return {string} A string with all HTML tags removed.
5532
+ */
5533
+ function noHtml(value) {
5534
+ if (value && typeof value === 'string') {
5535
+ // Use regular expression to remove all HTML tags
5536
+ return value.replace(/<[^>]*>.*?<\/[^>]*>|<[^>]+>/g, '');
5537
+ }
5538
+ else {
5539
+ return value;
5540
+ }
5541
+ }
5542
+ /**
5543
+ * Truncates the given HTML string to the specified maximum length, ensuring that the truncation
5544
+ * does not break HTML structure and attempts to truncate at word or tag boundaries when possible.
5545
+ * Appends an ellipsis (" (...)") to indicate truncation if the content exceeds the maximum length.
5546
+ *
5547
+ * @param {string} html - The HTML string to be truncated.
5548
+ * @param {number} maxLength - The maximum length for the truncated string, including the ellipsis.
5549
+ * @return {string} The truncated HTML string, or the original HTML string if its length is within the maximum length.
5550
+ */
5551
+ function truncateHtml(html, maxLength) {
5552
+ maxLength = maxLength ?? 0;
5553
+ if (!html || maxLength <= 0)
5554
+ return html;
5555
+ if (html?.length > maxLength) {
5556
+ const endIndex = Math.max(html.lastIndexOf(' ', maxLength), html.lastIndexOf('<', maxLength));
5557
+ return html.substring(0, endIndex) + ' (...)';
5558
+ }
5559
+ return html;
5560
+ }
5561
+
5562
+ /**
5563
+ * A custom Angular pipe that removes all HTML tags from a provided string.
5564
+ * This is useful for cases where HTML content needs to be sanitized or plain text is required.
5565
+ * Applies a function to strip HTML tags from the input value.
5566
+ *
5567
+ * It implements the `PipeTransform` interface provided by Angular to define its transformation logic.
5538
5568
  */
5539
5569
  class NoHtmlPipe {
5540
5570
  transform(value) {
@@ -5597,6 +5627,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5597
5627
  name: 'safeStyle',
5598
5628
  }]
5599
5629
  }], ctorParameters: () => [{ type: i1$2.DomSanitizer }] });
5630
+ /**
5631
+ * A custom Angular pipe that truncates an HTML string to a specified maximum length.
5632
+ * This pipe ensures that the HTML structure remains valid and properly closed,
5633
+ * even after truncation.
5634
+ *
5635
+ * It uses the `truncateHtml` function internally to handle the truncation logic.
5636
+ * This can be useful when there is a need to display a shortened version of an HTML
5637
+ * formatted string while preserving its structure.
5638
+ *
5639
+ * @pipe TruncateHtmlPipe
5640
+ * @member {string} name - The name to use for this pipe in Angular templates.
5641
+ * @method transform - Takes an HTML string input and truncates it to the specified length.
5642
+ * @param value - The HTML string to be truncated.
5643
+ * @param maxLength - The maximum length for the truncated string.
5644
+ * @returns The truncated HTML string with valid structure.
5645
+ */
5646
+ class TruncateHtmlPipe {
5647
+ transform(value, maxLength) {
5648
+ return truncateHtml(value, maxLength);
5649
+ }
5650
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TruncateHtmlPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
5651
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: TruncateHtmlPipe, name: "truncateHtml" });
5652
+ }
5653
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TruncateHtmlPipe, decorators: [{
5654
+ type: Pipe,
5655
+ args: [{
5656
+ name: 'truncateHtml',
5657
+ }]
5658
+ }] });
5600
5659
 
5601
5660
  class DisplayWithPipe {
5602
5661
  transform(value, displayFn) {
@@ -5997,6 +6056,7 @@ const components$1 = [
5997
6056
  SafeHtmlPipe,
5998
6057
  SafeStylePipe,
5999
6058
  NoHtmlPipe,
6059
+ TruncateHtmlPipe,
6000
6060
  DisplayWithPipe,
6001
6061
  FirstTruePipe,
6002
6062
  FirstFalsePipe,
@@ -6082,6 +6142,7 @@ class SharedPipesModule {
6082
6142
  SafeHtmlPipe,
6083
6143
  SafeStylePipe,
6084
6144
  NoHtmlPipe,
6145
+ TruncateHtmlPipe,
6085
6146
  DisplayWithPipe,
6086
6147
  FirstTruePipe,
6087
6148
  FirstFalsePipe,
@@ -6163,6 +6224,7 @@ class SharedPipesModule {
6163
6224
  SafeHtmlPipe,
6164
6225
  SafeStylePipe,
6165
6226
  NoHtmlPipe,
6227
+ TruncateHtmlPipe,
6166
6228
  DisplayWithPipe,
6167
6229
  FirstTruePipe,
6168
6230
  FirstFalsePipe,
@@ -13073,6 +13135,7 @@ const environment = Object.freeze({
13073
13135
  feed: {
13074
13136
  jsonFeed: {
13075
13137
  fr: [
13138
+ '/api/feed.json',
13076
13139
  'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/raw/master/doc/feed/feed-fr.json',
13077
13140
  // Example with JsonFeed version 1 (and not 1.1)
13078
13141
  //'https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-fr.json',
@@ -13905,7 +13968,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
13905
13968
  type: Injectable,
13906
13969
  args: [{
13907
13970
  providedIn: 'root',
13908
- //deps: [APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS]
13971
+ deps: [APP_LOCALES],
13909
13972
  }]
13910
13973
  }], ctorParameters: () => [{ type: i2$1.Platform }, { type: i1$1.TranslateService }, { type: i2$2.Storage }, { type: Environment, decorators: [{
13911
13974
  type: Inject,
@@ -19587,12 +19650,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
19587
19650
  type: Optional
19588
19651
  }] }] });
19589
19652
 
19653
+ const PEER_URL_REGEXP = /^(http|https):\/\/[^ "?#@]+$/;
19654
+ const NETWORK_DEFAULT_CONNECTION_TIMEOUT = 10000; // 10s - /!\ should be high (e.g. for poor connection)
19590
19655
  const NetworkRefreshTimerPeriod = {
19591
19656
  MOBILE: 1000 * 60 * 10 /* every 10 min */,
19592
19657
  DESKTOP: 1000 * 60 * 5 /* every 5 min */,
19593
19658
  };
19594
- const PEER_URL_REGEXP = /^(http|https):\/\/[^ "?#@]+$/;
19595
- const NETWORK_DEFAULT_CONNECTION_TIMEOUT = 10000; // 10s - /!\ should be high (e.g. for poor connection)
19596
19659
  /* -- DEV only (to debug refresh timer)
19597
19660
  NetworkRefreshTimerPeriod.MOBILE = 1000;
19598
19661
  NetworkRefreshTimerPeriod.DESKTOP = 1000; */
@@ -19618,6 +19681,7 @@ class NetworkService extends StartableObservableService {
19618
19681
  _deviceConnectionType;
19619
19682
  _forceOffline;
19620
19683
  _connectionTimeout;
19684
+ _connectionParams = {};
19621
19685
  _listeners = {};
19622
19686
  get online() {
19623
19687
  return this.connectionType !== 'none';
@@ -19646,6 +19710,9 @@ class NetworkService extends StartableObservableService {
19646
19710
  get connectionTimeout() {
19647
19711
  return this._connectionTimeout;
19648
19712
  }
19713
+ get connectionParams() {
19714
+ return this._connectionParams;
19715
+ }
19649
19716
  constructor(_document, platform, modalCtrl, storage, settings, cache, http, environment, loggingService, translate, toastController) {
19650
19717
  super(platform);
19651
19718
  this._document = _document;
@@ -19964,15 +20031,47 @@ class NetworkService extends StartableObservableService {
19964
20031
  console.debug(`[network] All cache cleared, in ${Date.now() - now}ms`);
19965
20032
  });
19966
20033
  }
19967
- async fetch(url) {
19968
- if (!url)
19969
- throw new Error('Missing url');
19970
- try {
19971
- return firstValueFrom(this.http.get(url));
20034
+ /**
20035
+ * Sends a GET request to the specified path and returns a promise of the response.
20036
+ *
20037
+ * @param {string} path The endpoint path to send the GET request to.
20038
+ * @param {Object} [opts] Optional parameters for the GET request.
20039
+ * @param {HttpHeaders | Object} [opts.headers] Headers to include in the request. Can be an instance of HttpHeaders or an object with header key-value pairs.
20040
+ * @param {'json'} [opts.responseType] The type of response expected. Defaults to 'json'.
20041
+ * @param {boolean} [opts.nocache] If true, indicates that the response should not be cached.
20042
+ * @param {number} [opts.timeout] The timeout for the request in milliseconds.
20043
+ * @return {Promise<T>} A promise that resolves with the response of type T.
20044
+ */
20045
+ get(path, opts) {
20046
+ const url = this.getUri(path);
20047
+ // Add App headers only if on same peer
20048
+ if (this.peer && url?.startsWith(this.peer.url)) {
20049
+ opts = this.addAppHeaders(opts);
19972
20050
  }
19973
- catch (err) {
19974
- console.error(`[network] Error fetching data from ${url}:`, err);
19975
- return null;
20051
+ return HttpUtils.getJson(this.http, url, opts);
20052
+ }
20053
+ async setAuthToken(token) {
20054
+ if (token) {
20055
+ console.debug('[network] Apply token authentication to headers');
20056
+ this._connectionParams.authToken = token;
20057
+ }
20058
+ // Clean auth token
20059
+ else if (this._connectionParams.authToken) {
20060
+ console.debug('[network] Remove token authentication from headers');
20061
+ delete this._connectionParams.authToken;
20062
+ await this.clearCache();
20063
+ }
20064
+ }
20065
+ async setAuthBasic(basic) {
20066
+ if (basic) {
20067
+ console.debug('[graphql] Apply basic authentication to headers');
20068
+ this._connectionParams.authBasic = basic;
20069
+ }
20070
+ // Clean auth basic
20071
+ else if (this._connectionParams.authBasic) {
20072
+ console.debug('[graphql] Remove basic authentication from headers');
20073
+ delete this._connectionParams.authBasic;
20074
+ await this.clearCache();
19976
20075
  }
19977
20076
  }
19978
20077
  /* -- protected functions -- */
@@ -20106,16 +20205,10 @@ class NetworkService extends StartableObservableService {
20106
20205
  this._timerSubscription.add(() => console.debug('[network] Refresh timer stopped'));
20107
20206
  }
20108
20207
  async getText(path, opts) {
20109
- return HttpUtils.getText(this.http, this.getUri(path), this.addVersionHeader(opts));
20110
- }
20111
- get(path, opts) {
20112
- return HttpUtils.getJson(this.http, this.getUri(path), this.addVersionHeader(opts));
20208
+ return HttpUtils.getText(this.http, this.getUri(path), this.addAppHeaders(opts));
20113
20209
  }
20114
20210
  /* -- Protected methods -- */
20115
- addVersionHeader(opts) {
20116
- // Only add version headers if enabled in environment
20117
- if (!this.environment.sendAppVersionHeaders)
20118
- return opts;
20211
+ addAppHeaders(opts) {
20119
20212
  const updatedOpts = { ...opts };
20120
20213
  if (!updatedOpts.headers) {
20121
20214
  updatedOpts.headers = {};
@@ -20123,25 +20216,63 @@ class NetworkService extends StartableObservableService {
20123
20216
  // Handle HttpHeaders instance
20124
20217
  if (updatedOpts.headers instanceof HttpHeaders) {
20125
20218
  let headers = updatedOpts.headers;
20126
- // Add application version header
20127
- if (this.environment.version) {
20128
- headers = headers.append('X-App-Version', this.environment.version);
20129
- }
20130
- // Add application name header
20131
- if (this.environment.defaultAppName) {
20132
- headers = headers.append('X-App-Name', this.environment.defaultAppName);
20219
+ // Add Authorization header
20220
+ const authorization = [];
20221
+ if (this._connectionParams.authToken) {
20222
+ authorization.push(`token ${this._connectionParams.authToken}`);
20223
+ }
20224
+ if (this._connectionParams.authBasic) {
20225
+ authorization.push(`Basic ${this._connectionParams.authBasic}`);
20226
+ }
20227
+ if (authorization.length > 0) {
20228
+ headers = headers.append('Authorization', authorization);
20229
+ }
20230
+ // Add Accept-Language header using settings.locale
20231
+ const locale = this.settings.locale;
20232
+ if (locale) {
20233
+ headers = headers.append('Accept-Language', locale);
20234
+ }
20235
+ // Only add version headers if enabled in environment
20236
+ if (this.environment.sendAppVersionHeaders) {
20237
+ // Add application version header
20238
+ if (this.environment.version) {
20239
+ headers = headers.append('X-App-Version', this.environment.version);
20240
+ }
20241
+ // Add application name header
20242
+ if (this.environment.defaultAppName) {
20243
+ headers = headers.append('X-App-Name', this.environment.defaultAppName);
20244
+ }
20133
20245
  }
20134
20246
  updatedOpts.headers = headers;
20135
20247
  }
20136
20248
  else {
20137
20249
  // Handle plain object headers
20138
- // Add application version header
20139
- if (this.environment.version) {
20140
- updatedOpts.headers['X-App-Version'] = this.environment.version;
20141
- }
20142
- // Add application name header
20143
- if (this.environment.defaultAppName) {
20144
- updatedOpts.headers['X-App-Name'] = this.environment.defaultAppName;
20250
+ // Add Authorization header
20251
+ const authorization = [];
20252
+ if (this._connectionParams.authToken) {
20253
+ authorization.push(`token ${this._connectionParams.authToken}`);
20254
+ }
20255
+ if (this._connectionParams.authBasic) {
20256
+ authorization.push(`Basic ${this._connectionParams.authBasic}`);
20257
+ }
20258
+ if (authorization.length > 0) {
20259
+ updatedOpts.headers['Authorization'] = authorization;
20260
+ }
20261
+ // Add Accept-Language header using settings.locale
20262
+ const locale = this.settings.locale;
20263
+ if (locale) {
20264
+ updatedOpts.headers['Accept-Language'] = locale;
20265
+ }
20266
+ // Only add version headers if enabled in environment
20267
+ if (this.environment.sendAppVersionHeaders) {
20268
+ // Add application version header
20269
+ if (this.environment.version) {
20270
+ updatedOpts.headers['X-App-Version'] = this.environment.version;
20271
+ }
20272
+ // Add application name header
20273
+ if (this.environment.defaultAppName) {
20274
+ updatedOpts.headers['X-App-Name'] = this.environment.defaultAppName;
20275
+ }
20145
20276
  }
20146
20277
  }
20147
20278
  return updatedOpts;
@@ -20150,7 +20281,7 @@ class NetworkService extends StartableObservableService {
20150
20281
  let uri = path;
20151
20282
  // If path is not an URI: prepend with peer URL
20152
20283
  if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
20153
- let peerUrl = this.peer && this.peer.url;
20284
+ let peerUrl = this.peer?.url;
20154
20285
  // Remove trailing slash
20155
20286
  if (peerUrl.endsWith('/')) {
20156
20287
  peerUrl = peerUrl.substring(0, peerUrl.length - 1);
@@ -20257,13 +20388,13 @@ class GraphqlService extends StartableService {
20257
20388
  httpLink;
20258
20389
  network;
20259
20390
  storage;
20391
+ settings;
20260
20392
  environment;
20261
20393
  typePolicies;
20262
20394
  fragments;
20263
20395
  _networkStatusChanged$;
20264
20396
  httpParams;
20265
20397
  wsParams;
20266
- connectionParams = {};
20267
20398
  _defaultFetchPolicy;
20268
20399
  onNetworkError = new Subject();
20269
20400
  customErrors = {};
@@ -20277,13 +20408,17 @@ class GraphqlService extends StartableService {
20277
20408
  get defaultFetchPolicy() {
20278
20409
  return this._defaultFetchPolicy;
20279
20410
  }
20280
- constructor(platform, apollo, httpLink, network, storage, environment, typePolicies, fragments) {
20411
+ get connectionParams() {
20412
+ return this.network.connectionParams;
20413
+ }
20414
+ constructor(platform, apollo, httpLink, network, storage, settings, environment, typePolicies, fragments) {
20281
20415
  super(platform); // Wait platform
20282
20416
  this.platform = platform;
20283
20417
  this.apollo = apollo;
20284
20418
  this.httpLink = httpLink;
20285
20419
  this.network = network;
20286
20420
  this.storage = storage;
20421
+ this.settings = settings;
20287
20422
  this.environment = environment;
20288
20423
  this.typePolicies = typePolicies;
20289
20424
  this.fragments = fragments;
@@ -20296,30 +20431,6 @@ class GraphqlService extends StartableService {
20296
20431
  .pipe(throttleTime(300), filter(() => this.network.online), mergeMap(() => this.network.checkPeerAlive()), filter((alive) => !alive))
20297
20432
  .subscribe(() => this.network.setForceOffline(true, { showToast: true }));
20298
20433
  }
20299
- async setAuthToken(token) {
20300
- if (token) {
20301
- console.debug('[graphql] Apply token authentication to headers');
20302
- this.connectionParams.authToken = token;
20303
- }
20304
- // Clean auth token
20305
- else if (this.connectionParams.authToken) {
20306
- console.debug('[graphql] Remove token authentication from headers');
20307
- delete this.connectionParams.authToken;
20308
- await this.clearCache();
20309
- }
20310
- }
20311
- async setAuthBasic(basic) {
20312
- if (basic) {
20313
- console.debug('[graphql] Apply basic authentication to headers');
20314
- this.connectionParams.authBasic = basic;
20315
- }
20316
- // Clean auth basic
20317
- else if (this.connectionParams.authBasic) {
20318
- console.debug('[graphql] Remove basic authentication from headers');
20319
- delete this.connectionParams.authBasic;
20320
- await this.clearCache();
20321
- }
20322
- }
20323
20434
  /**
20324
20435
  * Allow to add a field resolver
20325
20436
  * (see doc: https://www.apollographql.com/docs/react/data/local-state/#handling-client-fields-with-resolvers)
@@ -20764,6 +20875,11 @@ class GraphqlService extends StartableService {
20764
20875
  if (authorization.length > 0) {
20765
20876
  headers = headers.append('Authorization', authorization);
20766
20877
  }
20878
+ // Add Accept-Language header using settings.locale
20879
+ const locale = this.settings.locale;
20880
+ if (locale) {
20881
+ headers = headers.append('Accept-Language', locale);
20882
+ }
20767
20883
  // Add application version headers (if enabled)
20768
20884
  if (this.environment.sendAppVersionHeaders) {
20769
20885
  if (this.environment.version) {
@@ -20987,7 +21103,7 @@ class GraphqlService extends StartableService {
20987
21103
  }
20988
21104
  return undefined;
20989
21105
  }
20990
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraphqlService, deps: [{ token: i2$1.Platform }, { token: i2$5.Apollo }, { token: i3$4.HttpLink }, { token: NetworkService }, { token: StorageService }, { token: ENVIRONMENT }, { token: APP_GRAPHQL_TYPE_POLICIES, optional: true }, { token: APP_GRAPHQL_FRAGMENTS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
21106
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraphqlService, deps: [{ token: i2$1.Platform }, { token: i2$5.Apollo }, { token: i3$4.HttpLink }, { token: NetworkService }, { token: StorageService }, { token: LocalSettingsService }, { token: ENVIRONMENT }, { token: APP_GRAPHQL_TYPE_POLICIES, optional: true }, { token: APP_GRAPHQL_FRAGMENTS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
20991
21107
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraphqlService, providedIn: 'root' });
20992
21108
  }
20993
21109
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraphqlService, decorators: [{
@@ -20995,7 +21111,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
20995
21111
  args: [{
20996
21112
  providedIn: 'root',
20997
21113
  }]
20998
- }], ctorParameters: () => [{ type: i2$1.Platform }, { type: i2$5.Apollo }, { type: i3$4.HttpLink }, { type: NetworkService }, { type: StorageService }, { type: Environment, decorators: [{
21114
+ }], ctorParameters: () => [{ type: i2$1.Platform }, { type: i2$5.Apollo }, { type: i3$4.HttpLink }, { type: NetworkService }, { type: StorageService }, { type: LocalSettingsService }, { type: Environment, decorators: [{
20999
21115
  type: Inject,
21000
21116
  args: [ENVIRONMENT]
21001
21117
  }] }, { type: undefined, decorators: [{
@@ -23111,8 +23227,8 @@ class AccountService extends BaseGraphqlService {
23111
23227
  this._remoteLocalSettingsKeys = options?.remoteLocalSettingsKeys || [];
23112
23228
  this.resetData();
23113
23229
  // Send auth token to the graphql layer, when changed
23114
- this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
23115
- this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));
23230
+ this.onAuthTokenChange.subscribe((token) => this.network.setAuthToken(token));
23231
+ this.onAuthBasicChange.subscribe((basic) => this.network.setAuthBasic(basic));
23116
23232
  // Force network to wait account service, after getting connection to the peer
23117
23233
  this.network.on('beforeTryOnlineFinish', async (online) => {
23118
23234
  // If online, wait a full restart, because it can force offline mode
@@ -28272,6 +28388,65 @@ class JobUtils {
28272
28388
  }
28273
28389
  }
28274
28390
 
28391
+ // Converts an ArrayBuffer directly to base64, without any intermediate 'convert to string then
28392
+ // use window.btoa' step. According to my tests, this appears to be a faster approach:
28393
+ // http://jsperf.com/encoding-xhr-image-data/5
28394
+ /*
28395
+ MIT LICENSE
28396
+ Copyright 2011 Jon Leighton
28397
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
28398
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
28399
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28400
+ */
28401
+ /**
28402
+ * Converts an ArrayBuffer into a Base64 encoded string.
28403
+ *
28404
+ * @param {ArrayBuffer} arrayBuffer - The buffer to be converted into a Base64 string.
28405
+ * @return {string} The Base64 encoded string representation of the provided ArrayBuffer.
28406
+ */
28407
+ function base64ArrayBuffer(arrayBuffer) {
28408
+ let base64 = '';
28409
+ const encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
28410
+ const bytes = new Uint8Array(arrayBuffer);
28411
+ const byteLength = bytes.byteLength;
28412
+ const byteRemainder = byteLength % 3;
28413
+ const mainLength = byteLength - byteRemainder;
28414
+ let a;
28415
+ let b;
28416
+ let c;
28417
+ let d;
28418
+ let chunk;
28419
+ // Main loop deals with bytes in chunks of 3
28420
+ for (let i = 0; i < mainLength; i += 3) {
28421
+ // Combine the three bytes into a single integer
28422
+ chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
28423
+ // Use bitmasks to extract 6-bit segments from the triplet
28424
+ a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
28425
+ b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12
28426
+ c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6
28427
+ d = chunk & 63; // 63 = 2^6 - 1
28428
+ // Convert the raw binary segments to the appropriate ASCII encoding
28429
+ base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
28430
+ }
28431
+ // Deal with the remaining bytes and padding
28432
+ if (byteRemainder === 1) {
28433
+ chunk = bytes[mainLength];
28434
+ a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
28435
+ // Set the 4 least significant bits to zero
28436
+ b = (chunk & 3) << 4; // 3 = 2^2 - 1
28437
+ base64 += `${encodings[a]}${encodings[b]}==`;
28438
+ }
28439
+ else if (byteRemainder === 2) {
28440
+ chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];
28441
+ a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
28442
+ b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4
28443
+ // Set the 2 least significant bits to zero
28444
+ c = (chunk & 15) << 2; // 15 = 2^4 - 1
28445
+ base64 += `${encodings[a]}${encodings[b]}${encodings[c]}=`;
28446
+ }
28447
+ return base64;
28448
+ }
28449
+
28275
28450
  class IPosition {
28276
28451
  latitude;
28277
28452
  longitude;
@@ -33570,23 +33745,14 @@ class JsonFeedUtils {
33570
33745
  feed.items.forEach((item) => {
33571
33746
  // Truncate items html
33572
33747
  if (item.content_html) {
33573
- const html = this.truncateHtml(item.content_html, opts);
33748
+ const html = truncateHtml(item.content_html, opts?.maxContentLength);
33574
33749
  item.truncated = html.length !== item.content_html.length;
33575
33750
  item.content_html = html;
33576
33751
  }
33577
33752
  });
33578
33753
  return feed;
33579
33754
  }
33580
- static truncateHtml(html, opts) {
33581
- if (!html)
33582
- return html;
33583
- const maxContentLength = opts?.maxContentLength ?? 0;
33584
- if (maxContentLength > 0 && html?.length > maxContentLength) {
33585
- const endIndex = Math.max(html.lastIndexOf(' ', maxContentLength), html.lastIndexOf('<', maxContentLength));
33586
- return html.substring(0, endIndex) + ' (...)';
33587
- }
33588
- return html;
33589
- }
33755
+ static truncateHtml = truncateHtml;
33590
33756
  /**
33591
33757
  * Migrate from old version 1.0 to 1.1
33592
33758
  * @param feed
@@ -33683,7 +33849,7 @@ class FeedService extends StartableService {
33683
33849
  const feeds = await Promise.all((urls || []).map(async (url) => {
33684
33850
  try {
33685
33851
  // Get JSON
33686
- const json = await this.network.fetch(url);
33852
+ const json = await this.network.get(url);
33687
33853
  console.debug(`${this._logPrefix}Loaded JSON from ${url}`, json);
33688
33854
  // Resolve feed
33689
33855
  return await this.resolveFeed(json, url, opts);
@@ -34009,11 +34175,11 @@ class FeedsComponent {
34009
34175
  return [];
34010
34176
  }
34011
34177
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedsComponent, deps: [{ token: ENVIRONMENT }, { token: APP_FEED_SERVICE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
34012
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FeedsComponent, selector: "app-feed", inputs: { debug: "debug", showHeader: "showHeader", headerColor: "headerColor", cardColor: "cardColor", shape: "shape", class: "class", feeds: "feeds", feedUrls: "feedUrls", maxAgeInMonths: "maxAgeInMonths", maxContentLength: "maxContentLength" }, host: { properties: { "class": "this.hostClass" } }, providers: [RxState], ngImport: i0, template: "@let feeds = feeds$ | async;\n\n@if (debug) {\n <app-debug [title]=\"'Feed'\">\n <p>\n hasFeeds?: {{ hasFeeds$ | async }}\n <br />\n feedUrls: {{ feedUrls$ | async | json }}\n <br />\n shape: {{ shape }}\n </p>\n </app-debug>\n}\n\n@if (feeds | isNotEmptyArray) {\n <!-- top header -->\n @if (showHeader && (feeds | arrayFirst); as feed) {\n <ion-item lines=\"none\" [color]=\"headerColor\" class=\"feed-header shape-{{ shape }}\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS' | translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\" shape=\"\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n <div class=\"feed-content shape-{{ shape }} ion-no-padding\" [class.has-header]=\"showHeader\">\n <!-- feeds -->\n @for (feed of feeds; track feed.feed_url; let firstFeed = $first; let lastFeed = $last) {\n <!-- items -->\n @for (item of feed.items; track item.id; let firstItem = $first; let lastItem = $last) {\n <ion-card\n [class.first]=\"firstFeed && firstItem\"\n [class.last]=\"lastFeed && lastItem\"\n [color]=\"cardColor !== 'light-transparent' ? cardColor : undefined\"\n >\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n <!-- Authors -->\n @for (author of item.authors || feed.authors; track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label class=\"author\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <ion-text class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>\n @if (!last) {\n &nbsp;\n }\n }\n </ion-text>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p [innerText]=\"item.content_text\"></p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [":host{display:block;height:calc(100% - 10px);max-height:fit-content;overflow:hidden;--feed-header-height: 48px;-webkit-box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px rgba(0,0,0,.14),0 1px 5px rgba(0,0,0,.12);-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:10px;--feed-border-radius: 4px;border-radius:var(--feed-border-radius);--ion-card-background: rgba(var(--ion-background-color-rgb), .6)}:host.shape-round{--feed-border-radius: 12px}ion-button{text-transform:unset;--color: rgba(var(--ion-color-contrast-rgb), .7)}ion-item.feed-header{height:var(--feed-header-height);margin:0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);border-radius:var(--feed-border-radius) var(--feed-border-radius) 0 0}ion-item.feed-header ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed-content{height:auto;overflow-y:auto;--margin-bottom: 8px}.feed-content.has-header{height:calc(100% - var(--feed-header-height, 0))}.feed-content ion-card{--top-radius: 4px;--bottom-radius: 4px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 var(--margin-bottom) 0;border-radius:var(--top-radius) var(--top-radius) var(--bottom-radius) var(--bottom-radius);--ion-card-color-contrast-rgb: var(--ion-color-contrast-rgb, var(--ion-color-dark-rgb, 0, 0, 0));--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card.first{--top-radius: 0}.feed-content ion-card.last{--margin-bottom: 0;--bottom-radius: 0}.feed-content ion-card ion-card-header ion-card-title{--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-avatar{--color: rgba(var(--ion-card-color-contrast-rgb), .6);border:1px solid var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-label{--color: rgba(var(--ion-card-color-contrast-rgb), .8);color:var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-note{--color: rgba(var(--ion-card-color-contrast-rgb), .6);color:var(--color)}.feed-content ion-card ion-card-header .tags{display:inline}.feed-content ion-card ion-card-header .tags a{color:rgba(var(--ion-card-color-contrast-rgb),.6)!important}.feed-content ion-card ion-card-content ion-text ::ng-deep img{max-width:100%;height:auto!important}\n"], dependencies: [{ kind: "component", type: i2$1.IonAvatar, selector: "ion-avatar" }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2$1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2$1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DebugComponent, selector: "app-debug", inputs: ["titlePrefix", "title", "enable", "expanded"] }, { kind: "directive", type: FeedDirective, selector: "feed,[feed]", inputs: ["feed"] }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.JsonPipe, name: "json" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: DateFromNowPipe, name: "dateFromNow" }, { kind: "pipe", type: NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: MapPipe, name: "map" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34178
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FeedsComponent, selector: "app-feed", inputs: { debug: "debug", showHeader: "showHeader", headerColor: "headerColor", cardColor: "cardColor", shape: "shape", class: "class", feeds: "feeds", feedUrls: "feedUrls", maxAgeInMonths: "maxAgeInMonths", maxContentLength: "maxContentLength" }, host: { properties: { "class": "this.hostClass" } }, providers: [RxState], ngImport: i0, template: "<!-- debug -->\n@if (debug) {\n <app-debug [title]=\"'Feed'\">\n <p>\n hasFeeds?: {{ hasFeeds$ | async }}\n <br />\n feedUrls: {{ feedUrls$ | async | json }}\n <br />\n shape: {{ shape }}\n </p>\n </app-debug>\n}\n\n@let feeds = feeds$ | async;\n@if (feeds | isNotEmptyArray) {\n <!-- top header -->\n @if (showHeader && (feeds | arrayFirst); as feed) {\n <ion-item lines=\"none\" [color]=\"headerColor\" class=\"feed-header shape-{{ shape }}\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS' | translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\" shape=\"\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n <div class=\"feed-content shape-{{ shape }} ion-no-padding\" [class.has-header]=\"showHeader\">\n <!-- feeds -->\n @for (feed of feeds; track feed.feed_url; let firstFeed = $first; let lastFeed = $last) {\n <!-- items -->\n @for (item of feed.items; track item.id; let firstItem = $first; let lastItem = $last) {\n <ion-card\n [class.first]=\"firstFeed && firstItem\"\n [class.last]=\"lastFeed && lastItem\"\n [color]=\"cardColor !== 'light-transparent' ? cardColor : undefined\"\n >\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n <!-- Authors -->\n @for (author of item.authors || feed.authors; track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label class=\"author\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <ion-text class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>\n @if (!last) {\n &nbsp;\n }\n }\n </ion-text>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p>\n <markdown [data]=\"item.content_text\" emoji></markdown>\n </p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [":host{display:block;height:calc(100% - 10px);max-height:fit-content;overflow:hidden;--feed-header-height: 48px;-webkit-box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px rgba(0,0,0,.14),0 1px 5px rgba(0,0,0,.12);-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:10px;--feed-border-radius: 4px;border-radius:var(--feed-border-radius);--ion-card-background: rgba(var(--ion-background-color-rgb), .6)}:host.shape-round{--feed-border-radius: 12px}ion-button{text-transform:unset;--color: rgba(var(--ion-color-contrast-rgb), .7)}ion-item.feed-header{height:var(--feed-header-height);margin:0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);border-radius:var(--feed-border-radius) var(--feed-border-radius) 0 0}ion-item.feed-header ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed-content{height:auto;overflow-y:auto;--margin-bottom: 8px}.feed-content.has-header{height:calc(100% - var(--feed-header-height, 0))}.feed-content ion-card{--top-radius: 4px;--bottom-radius: 4px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 var(--margin-bottom) 0;border-radius:var(--top-radius) var(--top-radius) var(--bottom-radius) var(--bottom-radius);--ion-card-color-contrast-rgb: var(--ion-color-contrast-rgb, var(--ion-color-dark-rgb, 0, 0, 0));--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card.first{--top-radius: 0}.feed-content ion-card.last{--margin-bottom: 0;--bottom-radius: 0}.feed-content ion-card ion-card-header ion-card-title{--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-avatar{--color: rgba(var(--ion-card-color-contrast-rgb), .6);border:1px solid var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-label{--color: rgba(var(--ion-card-color-contrast-rgb), .8);color:var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-note{--color: rgba(var(--ion-card-color-contrast-rgb), .6);color:var(--color)}.feed-content ion-card ion-card-header .tags{display:inline}.feed-content ion-card ion-card-header .tags a{color:rgba(var(--ion-card-color-contrast-rgb),.6)!important}.feed-content ion-card ion-card-content ion-text ::ng-deep img{max-width:100%;height:auto!important}\n"], dependencies: [{ kind: "component", type: i2$1.IonAvatar, selector: "ion-avatar" }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2$1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2$1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i4$2.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: DebugComponent, selector: "app-debug", inputs: ["titlePrefix", "title", "enable", "expanded"] }, { kind: "directive", type: MarkdownDirective, selector: "markdown,[markdown]" }, { kind: "directive", type: FeedDirective, selector: "feed,[feed]", inputs: ["feed"] }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.JsonPipe, name: "json" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: DateFromNowPipe, name: "dateFromNow" }, { kind: "pipe", type: NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: MapPipe, name: "map" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34013
34179
  }
34014
34180
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedsComponent, decorators: [{
34015
34181
  type: Component,
34016
- args: [{ selector: 'app-feed', providers: [RxState], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let feeds = feeds$ | async;\n\n@if (debug) {\n <app-debug [title]=\"'Feed'\">\n <p>\n hasFeeds?: {{ hasFeeds$ | async }}\n <br />\n feedUrls: {{ feedUrls$ | async | json }}\n <br />\n shape: {{ shape }}\n </p>\n </app-debug>\n}\n\n@if (feeds | isNotEmptyArray) {\n <!-- top header -->\n @if (showHeader && (feeds | arrayFirst); as feed) {\n <ion-item lines=\"none\" [color]=\"headerColor\" class=\"feed-header shape-{{ shape }}\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS' | translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\" shape=\"\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n <div class=\"feed-content shape-{{ shape }} ion-no-padding\" [class.has-header]=\"showHeader\">\n <!-- feeds -->\n @for (feed of feeds; track feed.feed_url; let firstFeed = $first; let lastFeed = $last) {\n <!-- items -->\n @for (item of feed.items; track item.id; let firstItem = $first; let lastItem = $last) {\n <ion-card\n [class.first]=\"firstFeed && firstItem\"\n [class.last]=\"lastFeed && lastItem\"\n [color]=\"cardColor !== 'light-transparent' ? cardColor : undefined\"\n >\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n <!-- Authors -->\n @for (author of item.authors || feed.authors; track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label class=\"author\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <ion-text class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>\n @if (!last) {\n &nbsp;\n }\n }\n </ion-text>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p [innerText]=\"item.content_text\"></p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [":host{display:block;height:calc(100% - 10px);max-height:fit-content;overflow:hidden;--feed-header-height: 48px;-webkit-box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px rgba(0,0,0,.14),0 1px 5px rgba(0,0,0,.12);-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:10px;--feed-border-radius: 4px;border-radius:var(--feed-border-radius);--ion-card-background: rgba(var(--ion-background-color-rgb), .6)}:host.shape-round{--feed-border-radius: 12px}ion-button{text-transform:unset;--color: rgba(var(--ion-color-contrast-rgb), .7)}ion-item.feed-header{height:var(--feed-header-height);margin:0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);border-radius:var(--feed-border-radius) var(--feed-border-radius) 0 0}ion-item.feed-header ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed-content{height:auto;overflow-y:auto;--margin-bottom: 8px}.feed-content.has-header{height:calc(100% - var(--feed-header-height, 0))}.feed-content ion-card{--top-radius: 4px;--bottom-radius: 4px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 var(--margin-bottom) 0;border-radius:var(--top-radius) var(--top-radius) var(--bottom-radius) var(--bottom-radius);--ion-card-color-contrast-rgb: var(--ion-color-contrast-rgb, var(--ion-color-dark-rgb, 0, 0, 0));--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card.first{--top-radius: 0}.feed-content ion-card.last{--margin-bottom: 0;--bottom-radius: 0}.feed-content ion-card ion-card-header ion-card-title{--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-avatar{--color: rgba(var(--ion-card-color-contrast-rgb), .6);border:1px solid var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-label{--color: rgba(var(--ion-card-color-contrast-rgb), .8);color:var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-note{--color: rgba(var(--ion-card-color-contrast-rgb), .6);color:var(--color)}.feed-content ion-card ion-card-header .tags{display:inline}.feed-content ion-card ion-card-header .tags a{color:rgba(var(--ion-card-color-contrast-rgb),.6)!important}.feed-content ion-card ion-card-content ion-text ::ng-deep img{max-width:100%;height:auto!important}\n"] }]
34182
+ args: [{ selector: 'app-feed', providers: [RxState], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- debug -->\n@if (debug) {\n <app-debug [title]=\"'Feed'\">\n <p>\n hasFeeds?: {{ hasFeeds$ | async }}\n <br />\n feedUrls: {{ feedUrls$ | async | json }}\n <br />\n shape: {{ shape }}\n </p>\n </app-debug>\n}\n\n@let feeds = feeds$ | async;\n@if (feeds | isNotEmptyArray) {\n <!-- top header -->\n @if (showHeader && (feeds | arrayFirst); as feed) {\n <ion-item lines=\"none\" [color]=\"headerColor\" class=\"feed-header shape-{{ shape }}\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS' | translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\" shape=\"\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n <div class=\"feed-content shape-{{ shape }} ion-no-padding\" [class.has-header]=\"showHeader\">\n <!-- feeds -->\n @for (feed of feeds; track feed.feed_url; let firstFeed = $first; let lastFeed = $last) {\n <!-- items -->\n @for (item of feed.items; track item.id; let firstItem = $first; let lastItem = $last) {\n <ion-card\n [class.first]=\"firstFeed && firstItem\"\n [class.last]=\"lastFeed && lastItem\"\n [color]=\"cardColor !== 'light-transparent' ? cardColor : undefined\"\n >\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n <!-- Authors -->\n @for (author of item.authors || feed.authors; track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label class=\"author\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <ion-text class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>\n @if (!last) {\n &nbsp;\n }\n }\n </ion-text>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p>\n <markdown [data]=\"item.content_text\" emoji></markdown>\n </p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [":host{display:block;height:calc(100% - 10px);max-height:fit-content;overflow:hidden;--feed-header-height: 48px;-webkit-box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px rgba(0,0,0,.14),0 1px 5px rgba(0,0,0,.12);-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:10px;--feed-border-radius: 4px;border-radius:var(--feed-border-radius);--ion-card-background: rgba(var(--ion-background-color-rgb), .6)}:host.shape-round{--feed-border-radius: 12px}ion-button{text-transform:unset;--color: rgba(var(--ion-color-contrast-rgb), .7)}ion-item.feed-header{height:var(--feed-header-height);margin:0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);border-radius:var(--feed-border-radius) var(--feed-border-radius) 0 0}ion-item.feed-header ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed-content{height:auto;overflow-y:auto;--margin-bottom: 8px}.feed-content.has-header{height:calc(100% - var(--feed-header-height, 0))}.feed-content ion-card{--top-radius: 4px;--bottom-radius: 4px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 var(--margin-bottom) 0;border-radius:var(--top-radius) var(--top-radius) var(--bottom-radius) var(--bottom-radius);--ion-card-color-contrast-rgb: var(--ion-color-contrast-rgb, var(--ion-color-dark-rgb, 0, 0, 0));--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card.first{--top-radius: 0}.feed-content ion-card.last{--margin-bottom: 0;--bottom-radius: 0}.feed-content ion-card ion-card-header ion-card-title{--color: rgba(var(--ion-card-color-contrast-rgb), .87)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-avatar{--color: rgba(var(--ion-card-color-contrast-rgb), .6);border:1px solid var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-chip ion-label{--color: rgba(var(--ion-card-color-contrast-rgb), .8);color:var(--color)}.feed-content ion-card ion-card-header ion-card-subtitle ion-note{--color: rgba(var(--ion-card-color-contrast-rgb), .6);color:var(--color)}.feed-content ion-card ion-card-header .tags{display:inline}.feed-content ion-card ion-card-header .tags a{color:rgba(var(--ion-card-color-contrast-rgb),.6)!important}.feed-content ion-card ion-card-content ion-text ::ng-deep img{max-width:100%;height:auto!important}\n"] }]
34017
34183
  }], ctorParameters: () => [{ type: Environment, decorators: [{
34018
34184
  type: Inject,
34019
34185
  args: [ENVIRONMENT]
@@ -34613,13 +34779,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
34613
34779
 
34614
34780
  class FeedModule {
34615
34781
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
34616
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, declarations: [FeedsComponent, FeedDirective], imports: [SharedModule, i1$1.TranslateModule, SharedDebugModule], exports: [TranslateModule, FeedsComponent, FeedDirective] });
34617
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, imports: [SharedModule, TranslateModule.forChild(), SharedDebugModule, TranslateModule] });
34782
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, declarations: [FeedsComponent, FeedDirective], imports: [SharedModule, i1$1.TranslateModule, SharedDebugModule, SharedMarkdownModule], exports: [TranslateModule, FeedsComponent, FeedDirective] });
34783
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, imports: [SharedModule, TranslateModule.forChild(), SharedDebugModule, SharedMarkdownModule, TranslateModule] });
34618
34784
  }
34619
34785
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedModule, decorators: [{
34620
34786
  type: NgModule,
34621
34787
  args: [{
34622
- imports: [SharedModule, TranslateModule.forChild(), SharedDebugModule],
34788
+ imports: [SharedModule, TranslateModule.forChild(), SharedDebugModule, SharedMarkdownModule],
34623
34789
  declarations: [FeedsComponent, FeedDirective],
34624
34790
  exports: [TranslateModule, FeedsComponent, FeedDirective],
34625
34791
  }]
@@ -49985,5 +50151,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
49985
50151
  * Generated bundle index. Do not edit.
49986
50152
  */
49987
50153
 
49988
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FEED_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOME_CONFIG, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMarkdownContent, AppMarkdownModal, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, AppendQueryParamsPipePipe, ArrayDistinctPipe, ArrayFilterPipe, ArrayFindByPropertyPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayMapPipe, ArrayPluckPipe, ArraySortPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoResizeDirective, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DisplayWithPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FeedDirective, FeedModule, FeedService, FeedsComponent, FileResponse, FileService, FileSizePipe, FilesUtils, FirstFalsePipe, FirstPipe, FirstTruePipe, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldDefinitionUtils, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, IsValidDatePipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonFeedUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_PATTERNS, LAT_LONG_PATTERN_MAX_DECIMALS, LAT_LONG_VALUE_MAX_DECIMALS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MASK_RANGES, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapPipe, MapToPipe, MapValuesPipe, MarkdownDirective, MarkdownService, MarkdownTestPage, MarkdownTestingModule, MarkdownUtils, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatLatLongFieldInput, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NetworkUtils, NewTokenForm, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRINT_ID_QUERY_PARAM, PRINT_LOADING_STORAGE_KEY_PREFIX, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, PrintService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegExpUtils, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RoundPipe, RxStateComputed, RxStateModule, RxStateProperty, RxStateRegister, RxStateSelect, SCRYPT_PARAMS, SETTINGS_COMPACT_ROWS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_CONFIG_OPTIONS, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SafeStylePipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMarkdownModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, SplitArrayInChunksPipe, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, StrReplacePipe, SubMenuTabDirective, SwipeTestPage, TABLE_SETTINGS_ENUM, TOOLBAR_HEADER_ID, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ThrottledClickDirective, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, TruncHtmlPipe, TruncTextPipe, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UrlUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventNotificationModal, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, VersionUtils, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, compareVersionNumbers, computeDecimalDegrees, computeDecimalPart, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableAndClearControl, disableAndClearControls, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, enableRxStateProdMode, entityToString, equals, equalsOrNil, escapeRegExp, expansionAnimation, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, getUserAgent, hexToRgb, hexToRgbArray, initArrayControlsFromValues, interpolateString, intersectArrays, isAndroid, isBlankString, isCapacitor, isChrome, isControlHasInput, isEdge, isEmptyArray, isEntityService, isFirefox, isIOS, isInputElement, isInstanceOf, isInt, isIpad, isMacOS, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isPrint, isProgressEvent, isPromise, isResponseEvent, isSafari, isSameVersion, isStartableService, isTouchUi, isVersionCompatible, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, numberOrNilAttribute, numberToString, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputContentFromEvent, selectInputRange, setCalculatedValue, setControlEnabled, setControlsEnabled, setFormErrors, setPropertyByPath, setTabIndex, sleep, slideDownAnimation, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitArrayInChunks, splitById, splitByProperty, splitDegreesToDDArray, splitDegreesToDDMMArray, splitDegreesToDDMMSSArray, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
50154
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FEED_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOME_CONFIG, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMarkdownContent, AppMarkdownModal, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, AppendQueryParamsPipePipe, ArrayDistinctPipe, ArrayFilterPipe, ArrayFindByPropertyPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayMapPipe, ArrayPluckPipe, ArraySortPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoResizeDirective, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DisplayWithPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FeedDirective, FeedModule, FeedService, FeedsComponent, FileResponse, FileService, FileSizePipe, FilesUtils, FirstFalsePipe, FirstPipe, FirstTruePipe, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldDefinitionUtils, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, IsValidDatePipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonFeedUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_PATTERNS, LAT_LONG_PATTERN_MAX_DECIMALS, LAT_LONG_VALUE_MAX_DECIMALS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MASK_RANGES, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapPipe, MapToPipe, MapValuesPipe, MarkdownDirective, MarkdownService, MarkdownTestPage, MarkdownTestingModule, MarkdownUtils, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatLatLongFieldInput, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NetworkUtils, NewTokenForm, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRINT_ID_QUERY_PARAM, PRINT_LOADING_STORAGE_KEY_PREFIX, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, PrintService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegExpUtils, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RoundPipe, RxStateComputed, RxStateModule, RxStateProperty, RxStateRegister, RxStateSelect, SCRYPT_PARAMS, SETTINGS_COMPACT_ROWS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_CONFIG_OPTIONS, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SafeStylePipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMarkdownModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, SplitArrayInChunksPipe, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, StrReplacePipe, SubMenuTabDirective, SwipeTestPage, TABLE_SETTINGS_ENUM, TOOLBAR_HEADER_ID, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ThrottledClickDirective, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, TruncHtmlPipe, TruncTextPipe, TruncateHtmlPipe, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UrlUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventNotificationModal, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, VersionUtils, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, base64ArrayBuffer, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, compareVersionNumbers, computeDecimalDegrees, computeDecimalPart, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableAndClearControl, disableAndClearControls, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, enableRxStateProdMode, entityToString, equals, equalsOrNil, escapeRegExp, expansionAnimation, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, getUserAgent, hexToRgb, hexToRgbArray, initArrayControlsFromValues, interpolateString, intersectArrays, isAndroid, isBlankString, isCapacitor, isChrome, isControlHasInput, isEdge, isEmptyArray, isEntityService, isFirefox, isIOS, isInputElement, isInstanceOf, isInt, isIpad, isMacOS, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isPrint, isProgressEvent, isPromise, isResponseEvent, isSafari, isSameVersion, isStartableService, isTouchUi, isVersionCompatible, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, numberOrNilAttribute, numberToString, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputContentFromEvent, selectInputRange, setCalculatedValue, setControlEnabled, setControlsEnabled, setFormErrors, setPropertyByPath, setTabIndex, sleep, slideDownAnimation, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitArrayInChunks, splitById, splitByProperty, splitDegreesToDDArray, splitDegreesToDDMMArray, splitDegreesToDDMMSSArray, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, truncateHtml, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
49989
50155
  //# sourceMappingURL=sumaris-net.ngx-components.mjs.map